array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 MD5的部分碰撞 - 爱码网

原文地址:http://www.blogwind.com/Wuvist/comment.aspx?article_id=3138

唉……不知道怎么评价Huge Anderson每个星期给的challenge……每次都觉得很有挑战性,然后花上几十个小时在上面……

well……For a cup of coffee……

Huge这个星期给的挑战是寻找MD5 hash的部分碰撞……

确切的说,要我们找出md5 hash与“d024eac470132c7116d8ce8aa8409b8e”类似的文件

所谓类似,是说md5 hash出来的结果跟上面的有越多的连续相同的字符越好……位置也要一样……比方说:
d024eac470132c7116d8ce8aa8409b8e
9f038cc6a7ec9baad98c9dfc1aa6e3b8 便是有一个相同的……
9f038ac6a7ec9baad98c9dfc1aa6e3b8
便是有两个相同的……

企图碰运气是不实际的……只能写程序生成数以万计的文件计算md5 hash然后与“d024eac470132c7116d8ce8aa8409b8e”比较。

我的C++都几乎忘光了……实际上,我也从来没有用心去学C++。

只好使用VB.Net,虽然,我认为VB.Net程序的运行速度会比C++低。

然后,我真的很想去撞墙……

一直以来,我居然都把.Net framework提供的md5类库用错了……

System.Security.Cryptography.MD5CryptoServiceProvider生成的md5 hash是32 bytes的!!!

我居然一直以为是16bytes……并且使用在了博客风等系统上……唉……进行数据转换的时候,实在是有太多问题了……

应该使用下面的函数将返回的md5 hash字节数组转换为String:

Function ToHexString(ByVal bytes() As Byte) As String
        Dim str As New StringBuilder
        Dim i As Integer
        For i = 0 To bytes.Length - 1
         str.Append(Hex(bytes(i)))
        Next i

        Return str.ToString
End Function

这个bytes() to String的转换函数是从MSDN给的范例修改得来的。原程序是直接使用String,我将其修改成为StringBuilder以提高速度。

但是,很奇怪,有的时候并不能获得32位的十六进制数,有时是30位,有时是28位,实在想不明白是哪里出错了……要错,恐怕也只能是.Net的问题了……

插入一下……我还是不懂得如何从HexString转换到bytes()……否则,我的程序应该可以快很多……该死的类型转换……

我一开始,写程序自动随机生成128 bytes的文件,然后计算md5 checksum,并跟“d024eac470132c7116d8ce8aa8409b8e”做比较。

生成了一亿个文件,找到了7位连续相同的碰撞。

然后,随机生成十亿个256 bytes的文件……足足算了12个小时……找出来9位连续相同的碰撞……

这个结果证明了两件事情:
第一:我的运气很好--至于为什么说很好,下面有解释。
第二:我的电脑现在很稳定了,可以连续全符合工作12小时而不出任何问题。

9位连续相同的碰撞是所有学生作出来的结果中最好的……Finally, I win the cup of coffee.

md5的hash只是32 bytes而已,也就是说16^32种变化。

所以,无论是生成32 bytes还是64 bytes乃至256 bytes的随机文件,产生碰撞的可能性应该一样。但是,生成256 bytes的文件明显要比32 bytes的慢8倍左右。

试验证明也是如此,没有功夫再去等10亿个文件的统计,我只是重新做了一千万个文件的计算,分别是16 bytes, 32 bytes, 64 bytes,结果如下:

碰撞位数 碰撞次数 平均值 首次碰撞位置
4 1540 6493.506494 1147
5 96 104166.6667  12077
6 9 1111111.111  41748
4 1554 6435.006435  3574
5 103 97087.37864 359164
6 2500000.000 3096880
4 1597 6263.701847 2470
5 87 114942.52873 75989
6 6 1666666.6666 633064

看不出什么显著变化……

基本上,每找出多一位的碰撞,需要多检查16倍的文件……这个结果也是很合乎理解的……是十六进制的……

因为,有很多4位数的碰撞……每6400个文件便能找到一个四位连续碰撞这个数据很可信……乘16等于102400,跟做出来的5位碰撞也很相似……6位碰撞也是如此……照此推论……找出9位连续碰撞需要6710886400个文件……

(10位连续碰撞则是1073 7418 2400)

但是,我只是试了10亿个文件……所以,我的运气很好!!!其实也不见得很好……大家不妨注意一下第一次碰撞出现的位置……第一次出现的位置一般都是要比平均数低很多的……

或者,我一开始就应该生成16 bytes的文件……12小时大概就可以处理160亿个文件……那么,如果我的运气还是“很好”的话,便可能找到10位的连续碰撞了……

嗯嗯嗯……

其实,我说了这么多……

只是想说明一件事情:不要靠运气,你必须相信统计。

如果我运气真的真的很好的话……我是有可能试一个文件便找到完全的碰撞……但是,我试了10亿次……还是没有找到……

而我试了10亿次的结果,基本上是符合统计预测的。

上帝是不仍骰子的……大家不要赌博……

相关文章: