分类目录归档: 学习日志

中文字符串按拼音排序

汉字按拼音排序的问题比较复杂,不能通过简单比大小来排序,GB编码是可以的,但GBK编码就不行了。在网上找了很久,大多都是通过查表来实现的,这样就会增加程序的大小。
后来看到有一篇比较神奇的代码。
[cpp]
void GetFirstLetter(LPCTSTR strName, string &result)
{
static int li_SecPosValue[] = {
1601, 1637, 1833, 2078, 2274, 2302, 2433, 2594, 2787, 3106, 3212,
3472, 3635, 3722, 3730, 3858, 4027, 4086, 4390, 4558, 4684, 4925, 5249
};

static char* lc_FirstLetter[] = {
"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T", "W", "X", "Y", "Z"
};

static char* ls_SecondSecTable =
"CJWGNSPGCGNE[Y[BTYYZDXYKYGT[JNNJQMBSGZSCYJSYY[PGKBZGY[YWJKGKLJYWKPJQHY[W[DZLSGMRYPYWWCCKZNKYYGTTNJJNYKKZYTCJNMCYLQLYPYQFQRPZSLWBTGKJFYXJWZLTBNCXJJJJTXDTTSQZYCDXXHGCK[PHFFSS[YBGXLPPBYLL[HLXS[ZM[JHSOJNGHDZQYKLGJHSGQZHXQGKEZZWYSCSCJXYEYXADZPMDSSMZJZQJYZC[J[WQJBYZPXGZNZCPWHKXHQKMWFBPBYDTJZZKQHY"
"LYGXFPTYJYYZPSZLFCHMQSHGMXXSXJ[[DCSBBQBEFSJYHXWGZKPYLQBGLDLCCTNMAYDDKSSNGYCSGXLYZAYBNPTSDKDYLHGYMYLCXPY[JNDQJWXQXFYYFJLEJPZRXCCQWQQSBNKYMGPLBMJRQCFLNYMYQMSQYRBCJTHZTQFRXQHXMJJCJLXQGJMSHZKBSWYEMYLTXFSYDSWLYCJQXSJNQBSCTYHBFTDCYZDJWYGHQFRXWCKQKXEBPTLPXJZSRMEBWHJLBJSLYYSMDXLCLQKXLHXJRZJMFQHXHWY"
"WSBHTRXXGLHQHFNM[YKLDYXZPYLGG[MTCFPAJJZYLJTYANJGBJPLQGDZYQYAXBKYSECJSZNSLYZHSXLZCGHPXZHZNYTDSBCJKDLZAYFMYDLEBBGQYZKXGLDNDNYSKJSHDLYXBCGHXYPKDJMMZNGMMCLGWZSZXZJFZNMLZZTHCSYDBDLLSCDDNLKJYKJSYCJLKWHQASDKNHCSGANHDAASHTCPLCPQYBSDMPJLPZJOQLCDHJJYSPRCHN[NNLHLYYQYHWZPTCZGWWMZFFJQQQQYXACLBHKDJXDGMMY"
"DJXZLLSYGXGKJRYWZWYCLZMSSJZLDBYD[FCXYHLXCHYZJQ[[QAGMNYXPFRKSSBJLYXYSYGLNSCMHZWWMNZJJLXXHCHSY[[TTXRYCYXBYHCSMXJSZNPWGPXXTAYBGAJCXLY[DCCWZOCWKCCSBNHCPDYZNFCYYTYCKXKYBSQKKYTQQXFCWCHCYKELZQBSQYJQCCLMTHSYWHMKTLKJLYCXWHEQQHTQH[PQ[QSCFYMNDMGBWHWLGSLLYSDLMLXPTHMJHWLJZYHZJXHTXJLHXRSWLWZJCBXMHZQXSDZP"
"MGFCSGLSXYMJSHXPJXWMYQKSMYPLRTHBXFTPMHYXLCHLHLZYLXGSSSSTCLSLDCLRPBHZHXYYFHB[GDMYCNQQWLQHJJ[YWJZYEJJDHPBLQXTQKWHLCHQXAGTLXLJXMSL[HTZKZJECXJCJNMFBY[SFYWYBJZGNYSDZSQYRSLJPCLPWXSDWEJBJCBCNAYTWGMPAPCLYQPCLZXSBNMSGGFNZJJBZSFZYNDXHPLQKZCZWALSBCCJX[YZGWKYPSGXFZFCDKHJGXDLQFSGDSLQWZKXTMHSBGZMJZRGLYJB"
"PMLMSXLZJQQHZYJCZYDJWBMYKLDDPMJEGXYHYLXHLQYQHKYCWCJMYYXNATJHYCCXZPCQLBZWWYTWBQCMLPMYRJCCCXFPZNZZLJPLXXYZTZLGDLDCKLYRZZGQTGJHHGJLJAXFGFJZSLCFDQZLCLGJDJCSNZLLJPJQDCCLCJXMYZFTSXGCGSBRZXJQQCTZHGYQTJQQLZXJYLYLBCYAMCSTYLPDJBYREGKLZYZHLYSZQLZNWCZCLLWJQJJJKDGJZOLBBZPPGLGHTGZXYGHZMYCNQSYCYHBHGXKAMTX"
"YXNBSKYZZGJZLQJDFCJXDYGJQJJPMGWGJJJPKQSBGBMMCJSSCLPQPDXCDYYKY[CJDDYYGYWRHJRTGZNYQLDKLJSZZGZQZJGDYKSHPZMTLCPWNJAFYZDJCNMWESCYGLBTZCGMSSLLYXQSXSBSJSBBSGGHFJLYPMZJNLYYWDQSHZXTYYWHMZYHYWDBXBTLMSYYYFSXJC[DXXLHJHF[SXZQHFZMZCZTQCXZXRTTDJHNNYZQQMNQDMMG[YDXMJGDHCDYZBFFALLZTDLTFXMXQZDNGWQDBDCZJDXBZGS"
"QQDDJCMBKZFFXMKDMDSYYSZCMLJDSYNSBRSKMKMPCKLGDBQTFZSWTFGGLYPLLJZHGJ[GYPZLTCSMCNBTJBQFKTHBYZGKPBBYMTDSSXTBNPDKLEYCJNYDDYKZDDHQHSDZSCTARLLTKZLGECLLKJLQJAQNBDKKGHPJTZQKSECSHALQFMMGJNLYJBBTMLYZXDCJPLDLPCQDHZYCBZSCZBZMSLJFLKRZJSNFRGJHXPDHYJYBZGDLQCSEZGXLBLGYXTWMABCHECMWYJYZLLJJYHLG[DJLSLYGKDZPZXJ"
"YYZLWCXSZFGWYYDLYHCLJSCMBJHBLYZLYCBLYDPDQYSXQZBYTDKYXJY[CNRJMPDJGKLCLJBCTBJDDBBLBLCZQRPPXJCJLZCSHLTOLJNMDDDLNGKAQHQHJGYKHEZNMSHRP[QQJCHGMFPRXHJGDYCHGHLYRZQLCYQJNZSQTKQJYMSZSWLCFQQQXYFGGYPTQWLMCRNFKKFSYYLQBMQAMMMYXCTPSHCPTXXZZSMPHPSHMCLMLDQFYQXSZYYDYJZZHQPDSZGLSTJBCKBXYQZJSGPSXQZQZRQTBDKYXZK"
"HHGFLBCSMDLDGDZDBLZYYCXNNCSYBZBFGLZZXSWMSCCMQNJQSBDQSJTXXMBLTXZCLZSHZCXRQJGJYLXZFJPHYMZQQYDFQJJLZZNZJCDGZYGCTXMZYSCTLKPHTXHTLBJXJLXSCDQXCBBTJFQZFSLTJBTKQBXXJJLJCHCZDBZJDCZJDCPRNPQCJPFCZLCLZXZDMXMPHJSGZGSZZQLYLWTJPFSYASMCJBTZKYCWMYTCSJJLJCQLWZMALBXYFBPNLSFHTGJWEJJXXGLLJSTGSHJQLZFKCGNNNSZFDEQ"
"FHBSAQTGYLBXMMYGSZLDYDQMJJRGBJTKGDHGKBLQKBDMBYLXWCXYTTYBKMRTJZXQJBHLMHMJJZMQASLDCYXYQDLQCAFYWYXQHZ";

int H, L, W, j;
UINT i, stringlen = _tcslen(strName);
for (i = 0; i < stringlen; i++) {
H = (UCHAR) (strName[i + 0]);
L = (UCHAR) (strName[i + 1]);

if (H < 0xA1 || L < 0xA1) {
result += strName[i];
continue;
} else {
W = (H - 160) * 100 + L - 160;
}

if (W > 1600 && W < 5590) {
for (j = 22; j >= 0; j--) {
if (W >= li_SecPosValue[j]) {
result += lc_FirstLetter[j];
i ++;
break;
}
}

continue;
} else {
i++;
W = (H - 160 - 56) * 94 + L - 161;
if (W >= 0 && W <= 3007)
result += ls_SecondSecTable[W];
else {
result += (char) H;
result += (char) L;
}
}
}
}
[/cpp]
具体原理不清,原作者不清,但是能用,能获取到中文字符串拼音的首字母。如 小邓 = XD 小米 = XM 这样就可以通过 XD XM 比较来排序了。

优化Go自带的http.FileServer

最近发现一个不错的用go语言写的静态博客程序gor,原理是用gor程序生成整站静态的html网页。

我把它放在了阿里云上测试,发现打开网站速度有点慢,同样的我现在博客非静态的都比他快。

后查原因,原来gor直接调用go自带的http.FileServer实现web服务,而Go自带的http.FileServer没有对文本文件进行优化,浪费了大量带宽,如css、js等文本文件可以进行gzip压缩(Content-Encoding gzip),如jpg、js、css等不常变的文件可以设置在浏览器本地缓存时限(Expires Sat, 08 Jun 2013 19:42:15 GMT)。

阅读 Go\\src\\pkg\\net\\http\\fs.go 源码发现不是很深奥,自己有时间可以动手改。

有趣的是发现 七牛存储 整站也没有进行优化。

-------------------------------------------------------------------------------------------------
后续发现 FileServer 带有 Last-Modified 标签,这个是文件最后修改时间,当浏览器再次请求同一文件时 会把 Last-Modified 加入到请求 If-Modified-Since 标签,服务器收到后跟服务器端对比如果没有改变则返回304,否则返回新的文件。
而Expires标签不同,只要浏览器发现文件没过期,就不会发送询问文件有没修改的请求,这样就减轻了服务器的压力。

【转】iTunes的数字版权保护FairPlay

iTunes Store使用了一种苹果专有的、被称为FairPlay的加密方法来作为其数字版权管理方案。在购买歌曲以后,文件将在下载过程中被加密。

FairPlay是苹果公司使用的数字版权管理(DRM)系统,用来加密iTunes上受版权保护的媒体文件。在FairPlay下加密的媒体可以被同时传输到无限量的iPod/iPhone上或者在五台授权计算机上。FairPlay的音轨也可以被刻录到一个音频CD达七次。

Fairplay始于Veridisc创造的技术,其中多个密钥被用来验证和解密个人音频。每次用户请求一个新机器来播放FairPlay加密过的视频或者音频媒体,iTunes都要请求苹果公司的服务器。苹果公司返回和用户帐号信息相关的所有用户密钥。这就保证了苹果公司有能力限制被授权播放购买的媒体的计算机数目,也保证了每台授权PC都能有播放媒体的所需的所有密钥。

苹果公司不向任何人颁发FairPlay许可证,因此用户只能使用iTunes软件播放受保护的文件,并且只能在iPod或iPhone手机上播放。而同时iPod/iPhone只接受FairPlay方式的版权保护,播放不了其他DRM(例如微软或者REAL的DRM)保护的媒体内容。也就是说苹果公司已经将iTunes和iPod/iPhone有效地捆绑在了一起,形成了数字娱乐行业的垄断。

但其实苹果并不想这么做。事实上,iTunes出售DRM音乐并非出于自愿,而是唱片业者的策略使然。唱片业者为避免苹果在数码音乐市场一家独大,刻意对亚马逊(Amazon.com)、奈普斯特(Napster)等音乐站点采行开放策略,准许出售不加密的非DRM音乐文件,好让这些厂商有足够竞争力对抗龙头大厂苹果,对于苹果则坚持要求全面采用DRM技术。不过对于音乐现在已经不存在这个问题了,经过苹果公司创办人乔布斯对唱片业者要求对苹果与其他竞争对手一视同仁的呼吁,现在从iTunes Store下载的音乐不再有FairPlay保护了。但视频文件仍然是有FairPlay保护的。

原文链接:http://blog.bluesky.cn/archives/553/ituness-fairplay-drm.html

Discuz! X2.5升Discuz! X3.0的一个小问题

Discuz! X2.5 Release 20130426 后台自动升级到Discuz! X3 Release 20130524 时遇到 “文件 static/image/postbg/3.jpg 下载出现问题,请查看您的服务器网络以及data目录是否有写权限,请确认无误后点击确定”,登录服务器查看写权限什么的都是正常的,删了点继续升级还是会出现这个问题。

后来查看/data/update/updatelist.tmp里3.jpg的MD5 是af07b4addc6fdfdcfa121e4ce84dc7f9 和 自动升级下载的/data/update/static/image/postbg/3.jpg文件的md5 eb3954c5227986aeb912075ad50e7ec1 不匹配,原因已找到。

办法是把updatelist.tmp里3.jpg的MD5 改成 eb3954c5227986aeb912075ad50e7ec1 不然一直跳不过去,就这样升级通过了。

升级完后 在后台的 工具->文件检查 时有提示/static/image/postbg/3.jpg文件被修改过,办法是去官网下载Discuz! X3安装包 提取出/static/image/postbg/3.jpg文件覆盖被修改的文件。

vc6编译libcurl-7.30.0

下载
curl-7.30.0
http://curl.haxx.se/download/curl-7.30.0.zip
zlib-1.2.8
http://zlib.net/zlib128.zip
openssl-1.0.1e
http://www.openssl.org/source/openssl-1.0.1e.tar.gz

编译openssl
首先要安装 ActivePerl
命令行方式进入openssl目录
不使用“-DOPENSSL_USE_IPV6=0”参数会有一个结构未定义的错误。
C:\\openssl-1.0.1e\\perl Configure VC-WIN32 -DOPENSSL_USE_IPV6=0
C:\\openssl-1.0.1e\\ms\\do_ms
静态的 C:\\openssl-1.0.1e\\nmake -f ms\\nt.mak
动态的 C:\\openssl-1.0.1e\\nmake -f ms\\ntdll.mak
最会会输出到目录 C:\\openssl-1.0.1e\\out32dll

编译zlib
命令行方式进入zlib目录
nmake -f win32/Makefile.msc

最后编译libcurl
在curl-7.30.0\\lib目录下新建build.bat,输入以下内容

call "C:/Program Files/Microsoft Visual Studio/VC98/Bin/vcvars32.bat"
set CFG=release-dll-ssl-dll-zlib-dll
set OPENSSL_PATH=C:/openssl-1.0.1e
set ZLIB_PATH=C:/zlib-1.2.8
nmake -f Makefile.vc6

保存,然后运行。
如果已经装了February 2003 Platform SDK 还遇到 .\\curl_setup.h(588) : fatal error C1189: #error : MSVC 6.0 requires "February 2003 Platform SDK"
打开 Makefile.vc6 找 CFLAGS 宏 后面加 /I "C:\\Program Files\\Microsoft SDK\\include" 就ok了。我遇到的是vc6明明装了PSDK 目录也设了就是没找到。只能这样了。

最后就会在C:\\curl-7.30.0\\lib 目录输出dll 和 lib了

编译好的 libcurl-7.30.0