Friday, April 29, 2011

设置android开发环境

如何设置android开发环境?
官方网站已经写得很好了,http://developer.android.com/sdk/index.html,先看download,再看installing the sdk。顺着往下看基本没有什么跳转。
如果没有耐心看e问,可以参考1个视频教材。http://www.mars-droid.com/。很赞作者的奉献精神,每每深更半夜,还在声音洪亮地录视频。可见天才来自勤奋。同时有机会一定要为他多加宣传。

这个过程下来都还算顺利,只是在启动虚拟机的时候报错:emulator: ERROR: unknown virtual device name: '2.1'
stackoverflow上有针对的解决方案:Android emulator reports unknown virtual device
我用了方案2:不把.android目录放在用户目录下,然后设置路径ANDROID_SDK_HOME指向新的位置。
要说什么原因:很可能是因为我在c:\的用户目录不是真实的目录,已经是1个硬连接,导致android虚拟机水土不服。

最后还有1个小问题,不影响使用,就是有点不爽,有空请教一下大侠。
在eclipse中,第一次启动android sdk and avd manager的时候,总是要提示:location of the android sdk has not been setup in the perference。以后再去启动就完全正常了,avd也可以正常运行。

Thursday, April 28, 2011

RSA学习小结(更新)

在实际应用中,发现上次贴出来的测试代码里由不少问题,特此更新。
问题集中在:
1,怎么设置密钥相关变量mpuint的长度?
2,怎么设置明文、密文变量mpuint的长度?

原文是这么写的:
The variables d, e and n must be the same length, which must be an even multiple of 16 bits.
The source must be less than the modulus n(解密时,密文也应该小于n)

如果需要明文的ascii最大长度是64,

unsigned iMaxTextLen = 64;
unsigned iMaxKeyLen = (iMaxTextLen/2+2);
把64个byte换算成word。再加几个word,避免按照字符串输出时没有空结尾。
在加密解密过程中,所需mpuint的长度都可以初始化为iMaxKeyLen。

如果对数学原理很清楚的话,相信对上述问题就一目了然了。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
还有半小时下班,抓紧。
========================================================
RSA库:http://www.efgh.com/software/rsa.htm
选择理由:开源,简单明白。大侠推荐,品质保证。

========================================================
参考资料:
RSA库可选方案:RSA encryption library for c++,http://stackoverflow.com/questions/108518/rsa-encryption-library-for-c
RSA演示:http://people.eku.edu/styere/Encrypt/RSAdemo.html#genp
RSA加密演算法,http://zh.wikipedia.org/zh/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
同余,http://zh.wikipedia.org/wiki/%E5%90%8C%E4%BD%99
互质,http://zh.wikipedia.org/wiki/%E4%BA%92%E8%B3%AA
欧拉函数,http://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0

========================================================
测试代码:
注意:需要定义rsa库的外部函数

void numeric_overflow(void)
{
perror( "numeric overflow" );
abort();
}


#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <RsaLib\RSA.H>

int _tmain(int argc, _TCHAR* argv[])
{
printf("== mpuint功能测试 ===========================================\r\n");
mpuint i(2);
memset(i.value, 0, sizeof(*i.value)*i.length);

// mpuint单位长度:2个字节,1个unicode
printf("unsigned short.sizeof ===> %d\r\n", sizeof(unsigned short));
// mpuint总体长度:2个单位,4个字节,2个unicoder
printf("i.sizeof ===> %d\r\n", i.length * sizeof(*i.value));

{
printf("== 逐个单位的输入\r\n");
// 赋值
unsigned short *pValue = i.value;
pValue = i.value;
*pValue = 1;
pValue++;
*pValue = 3;

// 按mpuint单位输出
pValue = i.value;
for (size_t j=0; j<i.length; j++)
{
printf("i[%d] = %d\r\n", j, *pValue);
pValue++;
}

// edit:按照10进制输出到字符串
char szI[1024];
printf("i.edit ===> %s\r\n", i.edit(szI));
long l = atol(szI);
printf("i.edit.printf.0x ===> %0x\r\n", l);

// dump:按照mpuint.value[i]逐个输出到控制台
// 低位单元先输出,高位单元后输出
printf("i.dump ===>"); i.dump();

// scan: 用10进制形式的字符串给mpuint赋值
mpuint s(i.length);
const char* pszI = szI;
s.scan(pszI);
printf("i.edit.scan.dump ===>"); s.dump();
}

{
printf("== 输入字符串\r\n");
// 赋值
char szSource[] = {"ab"};
const char* pszSource = szSource;
memset(i.value, 0, i.length*sizeof(*i.value));
memcpy(i.value, szSource, strlen(szSource));
unsigned short *pValue = i.value;

// 按mpuint单位输出
pValue = i.value;
for (size_t j=0; j<i.length; j++)
{
printf("i[%d] = %d\r\n", j, *pValue);
pValue++;
}

// edit:按照10进制输出到字符串
char szI[1024];
printf("i.edit ===> %s\r\n", i.edit(szI));
long l = atol(szI);
printf("i.edit.printf.0x ===> %0x\r\n", l);

// dump:按照mpuint.value[i]逐个输出到控制台
// 低位单元先输出,高位单元后输出
printf("i.dump ===>"); i.dump();

// scan: 用10进制形式的字符串给mpuint赋值
mpuint s(i.length);
const char* pszI = szI;
s.scan(pszI);
printf("i.edit.scan.dump ===>"); s.dump();
}

printf("\r\n");
printf("== RSA功能测试 ==============================================\r\n");
// 最大(ascii)明文长度
unsigned iMaxTextLen = 64; // 521bit
unsigned iMaxKeyLen = (iMaxTextLen/2+2);

// 已知字符串形式的明文szSource
//
/* 超长 char szSource[] = {"1234567890123456789012345678901234567890123456789012345678901234_"}; */
char szSource[] = {"1234567890123456789012345678901234567890123456789012345678901234"};
// char szSource[] = {"HYTE7M1K4K9U4CW1_HYTE7M1K4K9U4CW1_HYTE7M1K4K9U4CW1"};
// char szSource[] = {"HYTE7M1K4K9U4CW1"};
// char szSource[] = {"HYTE7M1"};
unsigned iTextLen = (unsigned)strlen(szSource);
printf("szSource ===> %s\r\n", szSource);

// 生成密钥
// 注意:den必须长度一致, 而且是16bit的倍数
mpuint d(iMaxKeyLen); // 私钥.exponent
mpuint e(iMaxKeyLen); // 公钥.exponent
mpuint n(iMaxKeyLen); // moudle
/* 从字符串导入 */

char szD[] = "1366959476314201320612104229499274776898462169097826485636934\
0755196674896840342671642725095343222587647553252671687501273973225252986923047\
686286753753292800187223";
char szE[] = "7364464467100835015079598280779551627848613277390947205308161\
0017571755159810471970615094708039828625362188996500904870853267420683968471425\
23360654194537840151975";
char szN[] = "2551046374903721556165087556621364411613628475298617149406045\
5273705136007088455713120641125241943821666337305259447948524285690486822556554\
630571721143649549902363";
const char* pszScan;
d.scan(pszScan = szD);
e.scan(pszScan = szE);
n.scan(pszScan = szN);

/* 动态生成 */
// GenerateKeys(d, e, n);

char szKey[1024];
printf("d ===> "); d.dump(); printf("%s\r\n", d.edit(szKey));
printf("e ===> "); e.dump(); printf("%s\r\n", e.edit(szKey));
printf("n ===> "); n.dump(); printf("%s\r\n", n.edit(szKey));

// 加密:输入字符串形式的明文szSource和公钥pk, 输出字符串形式的密文szResult_Encrypt
// 注意:source必须小于n
mpuint source(iMaxKeyLen);
memset(source.value, 0, source.length*sizeof(*source.value));
memcpy(source.value, szSource, strlen(szSource));
printf("source ===> "); source.dump();
if (!(source < n))
{
printf("!!! assert ===> when encrypt, source < n. \r\n");
}

mpuint result_Encrypt(iMaxKeyLen);
EncryptDecrypt(result_Encrypt, source, e, n);
printf("result_Encrypt ===> "); result_Encrypt.dump();

char szResult_Encrypt[1024];
printf("%s\r\n", result_Encrypt.edit(szResult_Encrypt));

// 解密:输入字符串显示的密文szResult_Encrypt和私钥sk,输出字符串显示的明文
if (!(result_Encrypt < n)) // 注意:source必须小于n
{
printf("!!! assert ===> when decrypt, result_Encrypt < n. \r\n");
}

mpuint result_Decrypt_In(iMaxKeyLen);
const char* pszResult_EnCrypt = szResult_Encrypt;
result_Decrypt_In.scan(pszResult_EnCrypt);

mpuint result_Decrypt(iMaxKeyLen);
EncryptDecrypt(result_Decrypt, result_Decrypt_In, d, n);

printf("result_Decrypt ===> "); result_Decrypt.dump();

// 输出
printf("szResult ===> %s\r\n", (char*)(result_Decrypt.value));
printf("szSource ===> %s\r\n", szSource);

return 0;
}


========================================================
部分测试结果:

== mpuint功能测试
unsigned short.sizeof ===> 2
i.sizeof ===> 4
i[0] = 1
i[1] = 3
i.edit ===> 196609
i.edit.printf.0x ===> 30001
i.dump ===> 0001 0003
i.edit.scan.dump ===> 0001 0003

========================================================
哦也,15分钟完成。

Thursday, April 14, 2011

怎么启用google +1 服务?

lp出差,老人把孩子抢过去了,我可以自由了。

我也想试试看google的+1服务。

0,以为很简单,但是在google产品里没有发现入口。

1,又以为放狗去找“google +1”可以轻松搞定。找到了1条官方页面:http://www.google.com/+1/button/里面只有介绍,还是没有启用方法。

2,仔细看了介绍视频还是没说启用方法, 开始有点晕了。猜想可能在google account setting里有,就到里面翻箱倒柜,顺便也整理一下。其间思想开小差,注册了1个http://www.quora.com。之前在ip上看到这时1个关于提问/回答的网站。

3,想起我的google profile上的email is disable。了解+1需要显示推荐人的身份,相当于熟人的推荐才更可信(这也是我很喜欢上开心网的1部分原因)。开启email is on后,还是没有+1 tab。

4,现在的目标不再是开启+1服务了,已经转变为要考考自己怎么独立的解决1个问题了,至于这个问题是什么已经不重要了。总不能1有问题就去问大侠。

5,试试看quora,在上面发表了我的第一个问题:How can the Google +1 service be enabled?
 边上显示类似的问题:How can I get access to Google +1?
里面提示要到http://google.com/experimental,上去。
原来在Google Labs > Experimental search里,也太隐蔽了。是不是不好意思拿出来见人呀?

6,注册后,google主页显示“experiment lab”。搜1个“如何开启google +1服务”看看效果,果然有“+1”了。

7,顺便看到 为你的网站添加Google +1按钮| 爱谷地+1,也为自己的blogger申请+1服务。

8,回到google profile,还是没有+1 tab。是要这么做的:
这是人做的事吗?

9,再看+1tab,的确收藏了我的+1页面。可是毫无可读性,如下所示:
这活儿真的有点粗燥呀,有木有呀?

======================================================================
罗哩罗嗦报了1堆流水账,小结一下解决了3个问题:
1,怎么开启google +1 服务?
2,怎么为自己的网站预先申请+1服务?
3,怎么在google profile里显示+1 tab?

其实从+1介绍页面http://www.google.com/+1/button/的最后1行小字(Learn more about the +1 button and personalization on sites across the web.)出发,去读大段e文,不断跳转,应该也可以解决3个问题的。

其他感想:
1,自己解决问题的效率偏低。
也许是被这个官方页面给吓住了。后面的方法显得没有了条理。
针对具体问题,没有找到合适的答案,应该马上改用其他关键字。

2,quora的效率还是挺高的,不但可以马上找到类似问题。
我自己的提问的回复也很快到了。