Latent Dirichlet Allocation in Python

Shuyo's Weblog

Latent Dirichlet Allocation (LDA) is a language topic model.

In LDA, each document has a topic distribution and each topic has a word distribution.
Words are generated from topic-word distribution with respect to the drawn topics in the document.

However LDA’s estimation uses Variational Bayesian originally (Blei+ 2003), Collapsed Gibbs sampling (CGS) method is known as a more precise estimation.
So I tried implementing the CGS estimation of LDA in Python.

It requires Python 2.6, numpy and NLTK.


$ ./lda.py -h
Usage: lda.py [options]

Options:
-h, --help show this help message and exit
-f FILENAME corpus filename
-c CORPUS using range of Brown corpus' files(start:end)
--alpha=ALPHA parameter alpha
--beta=BETA parameter beta
-k K number of topics
-i ITERATION iteration count
-s smart initialize of parameters
--stopwords exclude stop words
--seed=SEED random seed
--df=DF threshold of document freaquency to cut words

$ ./lda.py -c 0:20 -k 10 --alpha=0.5 --beta=0.5…

View original post 32 more words

Topic modeling made just simple enough.

The Stone and the Shell

Right now, humanists often have to take topic modeling on faith. There are several good posts out there that introduce the principle of the thing (by Matt Jockers, for instance, and Scott Weingart). But it’s a long step up from those posts to the computer-science articles that explain “Latent Dirichlet Allocation” mathematically. My goal in this post is to provide a bridge between those two levels of difficulty.

Computer scientists make LDA seem complicated because they care about proving that their algorithms work. And the proof is indeed brain-squashingly hard. But the practice of topic modeling makes good sense on its own, without proof, and does not require you to spend even a second thinking about “Dirichlet distributions.” When the math is approached in a practical way, I think humanists will find it easy, intuitive, and empowering. This post focuses on LDA as shorthand for a broader family…

View original post 2,048 more words

实用为上

生活中的很多事情,归纳起来,最终都落脚到「实用为上」。

比如手机,比如MP3,从问世到如今,都经历了「从繁至简」,再「从简至繁」。
什么意思?最初的手机功能很简单,只是解决了传呼机只能传递信息却不能即时通讯的问题。后来的手机功能越来越累赘,几乎演变成了「万能机」。而现如今,「优化大师」「清理大师」的流行、iPhone的流行、三星对安卓的改造,都可以归结为一个核心,就是实用为上,易用为主,繁琐的功能不要,这就是「从繁至简」。
MP3演变的过程几乎也一样。
再说博客:博客不流行的时候人们就不写东西么?我想记事本、邮箱应该是用的最多的吧,很「简单」的时代;博客流行的时候,群雄争霸、各路博客服务瞬间涌现,好像博客就是万能的;现如今,Tumblr貌似已经盖过了主流的博客服务,Jekyll和Octopress也很流行,流沙成金,洗去喧嚣繁华,博客功能慢慢返璞归真。这就是记录、分享的工具,仅此而已,还是简单点好。
这么多年,Blogger几乎没有变过。还是写到这里吧。

via Blogger http://nourlcn.ownlinux.net/2013/09/blog-talk.html

不到长城非好汉

image

俗话说「不到长城非好汉」,来北京快3年了,昨天才想起来去爬八达岭长城。

八达岭长城属于延庆,从市区过去有几种选择方案:

  • 到前门坐旅游专列,往返100+元;
  • 到德胜门坐919公交车,单程全价12元,公交卡打折;
  • 到北京北站做S2线,单程6元,可刷公交卡;

我和女朋友选择了坐S2线,一个多小时就到八达岭站了。

需要注意的是,S2列车上的乘务员会推销八达岭的优惠套票,忽悠你省了5元钱还省时间、省路程,实际上不仅没有优惠,反而比八达岭售票处的价格还贵。提醒去八达岭坐S2线路的朋友不要上当。

登城、出城、下山,一共用了不到3个小时的时间。登长城给我的主要感受就是——部分游客还停留在进化未完成的阶段,堪比孙悟空。当然,说的主要是中国游客。

孙悟空跑到五指山,以为自己了不起了,撒泡猴尿再写个「到此一游」。从八达岭长城后山走到前山,绝大部分城砖上面都有各种签名、留言、标记。热门的地方比如烽火台,旧的签名还未褪去,新的签名又覆盖上了几层。

这些写「到此一游」的人都是什么心理呢?装领导题字?还是人无我有的炫耀心理?


内容转自微信公众账号「码农日记」,微信搜索「antdiary」或扫描二维码即可订阅。

image

via 蚂蚁的网络日志 http://blog.ownlinux.net/2013/05/the-great-wall?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+antalk+%28Ant%27s+Log+on+the+Internet%29

晨光BT之死


标题只是个噱头,本文所探讨的内容严谨一点来讲应该是“类晨光
BT的资源交流平台运营模式的建模与(简单)分析”。

 

  • 简介


所谓的“晨光
BT”是一种校园内部(北京交通大学)资源交流平台,最大的特点就是盗版众多、内部使用速度非常快。在这种资源交换环境中,每个用户会给予一定的初始资源(CG中折算下来是20G),而在资源请求的过程中系统逐渐会对用户的“共享率”提出更高的要求。这一要求简单的说就是下载1G的东西需要上传1.5G或者更高。在使用的时候也许很少有人会对这一系统的运营(运行,系统非盈利性)为何能够正常运行感兴趣,本文对这一资源交流平台进行建模并进行了一些讨论。

 

  • 模型及演化


首先对这一问题进行建模:假定系统中有
n个用户,每个用户都拥有无限可被请求的资源,并给予一个起始贡献分值s,用户每下载其它用户的1个单位的资源将消耗ratio分值(在现存系统中ratio > 1,最高为1.5,这里看起来与现行CGBT不一样,但是换个角度,将共享率转换为实际还可以下载的流量就能看出是一致的了)。


演化模型
1:选定cn(如c = 0.1)个用户为资源大户(大家感兴趣的资源都在他们那儿,是流量产出的主要来源)。在以下t步过程中的每一步,任意一个用户(包括资源大户)将以p(如0.9)的概率向大户请求1个单位的资源,以1 – p的概率向其它用户申请资源。


如果将这个系统看作能量交换,那么在没有外部能量注入的情况下,每交换一次资源,系统将损失能量
r-1。很显然,在次之后系统能量将只有初始状态的一半。但这并不是我所关心的,我更关心的是“用户死亡数”与t的关系。在这里选取一个时间点——半数用户处于“死亡”状态(无法再向其它用户申请资源,但是可以由其它用户向这个用户申请资源从而又活过来)的时间。

模型1的演化图 取n = 100,c = 0.1,s =
20.0, ratio = 1.5,p =
0.9,半数用户死亡时间是10(次)。图片是动态的,新浪博客的动态图片需要点“查看原图”才会看到动的。

 


既然系统能量是衰减的,那么什么样的因素能够延缓这一趋势呢?非播种员如果活动的概率较低,系统死亡一半用户的时间又是多少呢?进而可以在加入一个参数的情况下提出——


演化模型
2:与1不同之处在于增加一个活跃系数,设定播种员每一步都会有资源请求,而普通户则以概率access_probability(比如0.3)请求资源。

 

模型2
普通用户的请求概率与半数用户死亡时间的关系


演化模型
3:在2的基础上增加免费流量,另定义用户活动时有较小的概率mp申请免费资源。不再给出相应图表。

 

  •  结论


从上面的实验中可以看出,无论采用何种手段,系统死亡一半用户都是很迅速的。理解了系统的演化模式你就应该能够明白:

1.     

为什么
CGBT中会有多倍上传流量?为什么流量可以“买卖”?为什么经常要进行一些流量奖励的活动?


答:系统中最基本的运行是能量损耗的,必须从外部注入能量才能保持系统的正常运行。共享率越高,用户死得越快,因此我认为提高共享率并不是什么好事。

2.     

半数用户死亡,有这么夸张吗?为什么没有影响到我们的使用?


答:一、这个可以看看自己周围的人中有多少人的账号是不再使用的,最简单实在也是最严谨的是让管理员公布统计数据;二、
CGBT使用的人数基数大,有的人使用率非常非常低,半数用户死亡根本就不影响系统;另外CGBT每年还会有大量新生入驻,也是系统能量的巨大外部注入。

3.     

多数用户会死亡的根本原因是什么?


答:如果不能想清楚这个问题,那么这个实验就是失败的。用户死亡的根本原因就在于资源的集中性。大家感兴趣的资源不在普通手中,而在“播种员”手中,因而积分的流向总是从普通用户流到“播种员”或者“播种员”之间的。值得注意的是共享率只是决定死亡速度,高低并不影响结局。说句更远的,造成贫富差距主要原因之一就是(广义的)资源的集中性。

 

  •  其它
SkyDrive中提供了有相关的模拟实现代码(Python3写的,很简单),图表使用的是Matplotlib绘制,动态图是用Gephi生成然后制作的GIF。

 

  • 写在最后

   
这个演化模型的生命周期完全可以通过数学手段解决,但是我的功底还是太差了,用程序模拟演化有一个好处是可以将中间的演化过程更直观的表达出来。最后说一下做这个实验的初衷:我只是偶尔上
CGBT下点电影什么的,直到有一天我的号被封了,不能下种子,晚上8点以后还不准搜种子,找别人借来的账号下东西还提示“不能同时下载”什么什么的。我开始质疑“共享率”这个东西,像我这种需求不大的人,共享率怎么上得去?我又没有像实验室其它同学一样从来不关机通宵做种,哪里有那么多上传?我说我心疼已经“咔咔”作响的硬盘可以吗?(这种心态其实是不对的)一点点愤怒之余我动用了手上的服务器,整了几百G的东西放在那儿做种,共享率从1变到了6。但是这样做又有什么意义呢,还不如来做做这个实验。仅仅只是对系统的讨论,在这里仍然要感谢辛勤耕耘、无私分享的播种员们,是你们让我这研究生生活丰富了不少。
每当离别的时候我就会想起初一语文老师念到《从百草园到三味书屋》中的“Ade,我的蟋蟀们!Ade,我的覆盆子们和木莲们!”,感谢你们,感谢北交大,临行前来发这处子帖以示告别。

 青春就应该这样绽放  游戏测试:三国时期谁是你最好的兄弟!!  你不得不信的星座秘密

via Back and Forth http://blog.sina.com.cn/s/blog_439371b501018ikr.html

Install PyCharm and JDK on Ubuntu 12.04

Installing Sun JDK 7 on Ubuntu 12.04:
  • Download the sun jdk 7 tar file from here
  • Extract the tar file:
$ tar -xvzf jdk-7u4-linux-x64.tar.gz
  • Move extracted folder to this location:
$ sudo mv jdk1.7.0_04 /usr/lib/jvm/
  • Install new java source in system: 
$ sudo update-alternatives --install \
/usr/bin/javac javac /usr/lib/jvm/jdk1.7.0_04/bin/javac 1 
$ sudo update-alternatives --install \
/usr/bin/java java /usr/lib/jvm/jdk1.7.0_04/bin/java 1 
$ sudo update-alternatives --install \
/usr/bin/javaws javaws /usr/lib/jvm/jdk1.7.0_04/bin/javaws 1
  • Choose default java:
$ sudo update-alternatives --config javac 
$ sudo update-alternatives --config java 
$ sudo update-alternatives --config javaws
  • java version test:
$ java -version
  • Verify the symlinks all point to the new java location:
$ ls -la /etc/alternatives/java*
  • Enable Java plugin for Mozilla Firefox (even for Chrome)
#for 64-Bit jdk 
$ sudo ln -s /usr/lib/jvm/jdk1.7.0_04/jre/\
lib/amd64/libnpjp2.so /usr/lib/mozilla/plugins 
#for 32-Bit jdk 
$ sudo ln -s /usr/lib/jvm/jdk1.7.0_04/jre/\
lib/i386/libnpjp2.so /usr/lib/mozilla/plugins
  • JAVA_HOME configuration:
Some tools require JAVA_HOME variable. You can set JAVA_HOME in Ubuntu so simple: Edit the file .bashrc under your home directory and add the following lines: (if .bashrc is hidden click in Nautilus Menu View > Show Hidden Files)
export JAVA_HOME=/path/your/jdk 
export PATH=$JAVA_HOME/bin:$PATH

Install pycharm on ubuntu 12.04:
$ tar -xvzf pycharm-2.6.2.tar.gz 
$ cd /pycharm-2.6.2/bin/ 
$ ./pycharm.sh &

为什么应该放弃或减少使用MD5

MD5是一种常用的单向哈希算法。它被广泛用于以下几个用途:

  1. 检查数据是否一致。将两地存储的数据进行哈希,比较结果,如果结果一致就无需再进行数据比对。这是利用了其“抵抗冲突”(collision- resistant)的能力,两个不同的数据,其哈希值只有很小的几率一致。相当多数据服务,尤其是网盘服务,利用类似的做法来检测重复数据,避免重复上传。
  2. 存储用户密码。将密码哈希后的结果存储在数据库中,以做密码匹配。这是利用了其做为单向哈希的特点,从计算后的哈希值不能得到密码。
  3. 校验数据正确性。将数据和数据哈希后的结果一并传输,用于检验传输过程中数据是否有损坏。这是利用了很难找到两个不同的数据,其哈希结果一致的特点。

下面我们将说明为什么对于上面三种用途, MD5都不适用。

第一个用途尤其可怕。这个用途的最大的问题是,MD5在现实中已经被发现有相当多的数据都可能导致冲突。举例而言,如下两段数据的MD5哈希值就是完全一样的。

                   数据 1  

    4d c9 68 ff 0e e3 5c 20 95 72 d4 77 7b 72 15 87
    d3 6f a7 b2 1b dc 56 b7 4a 3d c0 78 3e 7b 95 18
    af bf a2 00 a8 28 4b f3 6e 8e 4b 55 b3 5f 42 75
    93 d8 49 67 6d a0 d1 55 5d 83 60 fb 5f 07 fe a2

                   数据 2

    4d c9 68 ff 0e e3 5c 20 95 72 d4 77 7b 72 15 87
    d3 6f a7 b2 1b dc 56 b7 4a 3d c0 78 3e 7b 95 18
    af bf a2 02 a8 28 4b f3 6e 8e 4b 55 b3 5f 42 75
    93 d8 49 67 6d a0 d1 d5 5d 83 60 fb 5f 07 fe a2

                 输出相同的MD5 哈希

           008ee33a9d58b51cfeb425b0959121c9

这意味着,如果用户提供数据 1,服务器已经存储数据 2。通过简单的MD5哈希方式检查重复,服务器上为用户保存的数据就是2。 接下来发生的事情大家都知道了,就是用户数据丢了!

第二个用途很容易遭到rainbow table攻击,和明文存储密码的实质区别不大。更详细的分析可以察看这篇文章

第三个用途里一般会在需要哈希的数据中混入某些秘密,也就是计算公式为md5(secret key + data)。 但这样并不适合用于验证数据的完整性。这是因为,从理论上上来说,如果知道md5(secret key +X),即使不知道secret key的内容, 仍然可能通过对X的分析,计算得到md5(secret key +Y),从而将X成功的替换成Y,导致接收方仍然认为数据是正确的。

via 九点 科技 http://blog.jianguoyun.com/?p=481

如何优雅地使用 Android 设备?

本人长期使用安卓,也短期使用过itouch4,说说个人经验.

  • 首先在设备选择上,建议尽量选择Google的亲儿子.

1.因为安卓升级是很快的.每次升级的进步也是看得见的.这样能够享受到最新的Android系统.
2.省去清理各运营商的各种定制软件.绑定的软件.
3.省去行货机器恢复Google服务.
(如果拿到一个行货运营商定制机,个人也会第一时间解锁,ROOT,清理,恢复google服务.没办法,这是个开放的系统.有很多折腾的空间.不是Android用户想折腾.而是被行货定制机折腾的太不优雅了.)

  • 桌面上,android爽过ios的就是桌面挂件了.

它相当于把桌面开了几个口子.让这些程序一直在桌面运行.这样更加能快速找到想要编辑的东西.
所以Android设备的桌面 一般可以不用放得像麻子一样成宫格状的图标,而是更加个性化的挂件.
打开手机,最常用的除了看时间就是看Google日历,这是我最常用的.我在上面安排自己的生活,也能看到女友的生活.还能有共享日历和朋友们一起关注一些新闻大事.
桌面挂件还可以是很多东西,甚至是自己的课程表.

  • 在软件上,除了不用各种类似360之类喜欢刷存在感的国产软件外.可以把不用的系统软件”停用”,这是不需要root也可以的.这样平时就在软件里表里面隐藏了,如需恢复,在应用管理找到并启用即可.

  • 浏览器方面,强烈的建议使用Chrome.

首先是本身好用,比如手势切换标签, 手指从屏幕左右划入即可.非常方便.
其次,在登录后,可以和电脑同步标签,你可以无缝的在不同设备切换上网.

用chrome还有个比较方便的是,他有系统本身的分享出口. 这一点非常好用.很多国产软件没有,不知道为什么. 也不知道ios有没有类似功能,
这一步我也教会了我妈,他经常用我给她的nexus s,通过chrome的分享,gmail发我一些健康知识文章.
这里推荐用pocket暂存一些网页,

  • 说到分享,再推荐一个图片编辑工具 evernote的插件:圈点.类似于QQ截图工具箱的效果.

音量- + 电源键 截图后.
在自带的照片查看器里面分享出口选择圈点

然后就可以快速进行各种圈圈点点,然后在发给别人了.

  • 另外,如果有两台带NFC的4.1机器,可以使用 android bean 背靠背,快速互传网页,照片等.非常神奇!
  • 在2.3以上的设备都可以自建热点来拖kindle,平板类,甚至笔记本设备来上网.

  • 再说软件方面,

视频播放器推荐MX player,虽然mobo player也很棒,还有悬浮窗,但是经过多次对比发现,MX player有时候放的更加流畅,而且使用系统默认控件,感觉很简单轻巧.

输入法推荐谷歌拼音, 之前用搜狗,但是通过提示更新词库来刷存在感,就忍着没有模糊音换谷歌了.

阅读器,虽然用了fipboard,新鲜汇,感觉都不错,不过最终还是觉得Greader最好用啊.

豌豆荚很好用.喜欢玩游戏的话拇指玩很不错.

推荐一个安卓壁纸,上面壁纸质量不错,而且几乎可以下下来作为电脑的壁纸.

  • 个人不喜欢装即时通讯软件,他们并非必要的.如gtalk,微信QQ之类.他们会推送意义不大的信息打断你.当你正在认真看一篇文章时,这时发来一个即时消息.你回也不是,不回也不是.回吧,可能就一直聊下去了,不回吧,心里一直惦记着.想着快点看完好回消息.就这样毁了你的阅读兴致.  当然这要看你的使用侧重了.本人用Gtalk只用来和女友聊天.

最后,在webos那个设计师跳槽到google之后,感觉安卓本身越来越优雅了,给人体验越来越良好,已经不是当年2.x卡成狗的系统了.在很多地方强于IOS. 
期待它将越来越好 ,可能不久知乎上会出现
 “安卓的体验很好,但有时候不得不使用ios,如何优雅的使用ios?”  的问题.

— 完 —

下载知乎 iPhone 客户端:http://zhi.hu/ios

via 知乎每日精选 http://www.zhihu.com/question/20494342/answer/15284529

如何安全的存储密码

过去一段时间来, 众多的网站遭遇用户密码数据库泄露事件, 这甚至包括顶级的互联网企业–NASDQ上市的商务社交网络Linkedin, 国内诸如CSDN一类的就更多了。

层出不穷的类似事件对用户会造成巨大的影响,因为人们往往习惯在不同网站使用相同的密码,一家“暴库”,全部遭殃。

那么在选择密码存储方案时, 容易掉入哪些陷阱, 以及如何避免这些陷阱? 坚果云,作为一个用于同步、备份文件的云存储服务提供者,在安全方面有一些心得,记录于此,与大家分享。

菜鸟方案

直接存储用户密码的明文或者将密码加密存储。

曾经有一次我在某知名网站重置密码,结果邮件中居然直接包含以前设置过的密码。我和客服咨询为什么直接将密码发送给用户,客服答曰:“减少用户步骤,用户体验更好”;再问“管理员是否可以直接获知我的密码”, 客服振振有词:“我们用XXX算法加密过的,不会有问题的”。 殊不知,密码加密后一定能被解密获得原始密码,因此,该网站一旦数据库泄露,所有用户的密码本身就大白于天下。

以后看到这类网站,大家最好都绕道而走,因为一家“暴库”,全部遭殃。

入门方案

将明文密码做单向哈希后存储。

单向哈希算法有一个特性,无法通过哈希后的摘要(digest)恢复原始数据,这也是“单向”二字的来源,这一点和所有的加密算法都不同。常用的单向哈希算法包括SHA-256, SHA-1, MD5等。例如,对密码“passwordhunter”进行SHA-256哈希后的摘要(digest)如下:
bbed833d2c7805c4bf039b140bec7e7452125a04efa9e0b296395a9b95c2d44c

可能是“单向”二字有误导性,也可能是上面那串数字唬人,不少人误以为这种方式很可靠, 其实不然。

单向哈希有两个特性:
1)从同一个密码进行单向哈希,得到的总是唯一确定的摘要
2)计算速度快。随着技术进步,尤其是显卡在高性能计算中的普及,一秒钟能够完成数十亿次单向哈希计算

结合上面两个特点,考虑到多数人所使用的密码为常见的组合,攻击者可以将所有密码的常见组合进行单向哈希,得到一个摘要组合, 然后与数据库中的摘要进行比对即可获得对应的密码。这个摘要组合也被称为rainbow table。

更糟糕的是,一个攻击者只要建立上述的rainbow table,可以匹配所有的密码数据库。仍然等同于一家“暴库”,全部遭殃。以后要是有某家厂商宣布“我们的密码都是哈希后存储的,绝对安全”,大家对这个行为要特别警惕并表示不屑。有兴趣的朋友可以搜索下,看看哪家厂商躺着中枪了。

进阶方案

将明文密码混入“随机因素“,然后进行单向哈希后存储,也就是所谓的”Salted Hash”。

这个方式相比上面的方案,最大的好处是针对每一个数据库中的密码,都需要建立一个完整的rainbow table进行匹配。 因为两个同样使用“passwordhunter”作为密码的账户,在数据库中存储的摘要完全不同。

10多年以前,因为计算和内存大小的限制,这个方案还是足够安全的,因为攻击者没有足够的资源建立这么多的rainbow table。 但是,在今日,因为显卡的恐怖的并行计算能力,这种攻击已经完全可行。

专家方案

故意增加密码计算所需耗费的资源和时间,使得任何人都不可获得足够的资源建立所需的rainbow table。

这类方案有一个特点,算法中都有个因子,用于指明计算密码摘要所需要的资源和时间,也就是计算强度。计算强度越大,攻击者建立rainbow table越困难,以至于不可继续。

这类方案的常用算法有三种:
1)PBKDF2(Password-Based Key Derivation Function)

PBKDF2简单而言就是将salted hash进行多次重复计算,这个次数是可选择的。如果计算一次所需要的时间是1微秒,那么计算1百万次就需要1秒钟。假如攻击一个密码所需的rainbow table有1千万条,建立所对应的rainbow table所需要的时间就是115天。这个代价足以让大部分的攻击者忘而生畏。

美国政府机构已经将这个方法标准化,并且用于一些政府和军方的系统。 这个方案最大的优点是标准化,实现容易同时采用了久经考验的SHA算法。

2) bcrypt

bcrypt是专门为密码存储而设计的算法,基于Blowfish加密算法变形而来,由Niels Provos和David Mazières发表于1999年的USENIX。

bcrypt最大的好处是有一个参数(work factor), 可用于调整计算强度,而且work factor是包括在输出的摘要中的。随着攻击者计算能力的提高,使用者可以逐步增大work factor,而且不会影响已有用户的登陆。

bcrypt经过了很多安全专家的仔细分析,使用在以安全著称的OpenBSD中,一般认为它比PBKDF2更能承受随着计算能力加强而带来的风险。bcrypt也有广泛的函数库支持,因此我们建议使用这种方式存储密码

3) scrypt

scrypt是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的。

和上述两种方案不同,scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。但是,scrypt在算法层面只要没有破绽,它的安全性应该高于PBKDF2和bcrypt。

采取行动:

看到这里,如果你产生了危机感,那么就行动起来:
1)如果你是普通用户,那么我们建议采取这种方案,对不同的网站使用不同的密码;
2)如果你是开发人员, 并且现在已经采取了简单的MD5哈希存储,请关注我们的后续文章。我们会讲述在保证用户正常登陆的情况下,如何进行密码迁移。

via 九点 科技 http://blog.jianguoyun.com/?p=438