犬者
“说了你又不听,听又不懂,懂又不做,做又做错,错又不认,认又不改,改又不服,不服也不说,那叫我怎么办?!”

【电脑】MD5的部分碰撞

唉……不知道怎么评价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亿次的结果,基本上是符合统计预测的。

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

3138
问天 @9/16/2004 8:56:00 AM
View blogs in this category:电脑


Please leave your comment here

 
  名字:
  主页:
  内容:
 

   


Navigation
Blogwind
犬者首页
Contact


个人档案


“说了你又不听,听又不懂,懂又不做,做又做错,错又不认,认又不改,改又不服,不服也不说,那叫我怎么办?!”



Categories
死结(27)
电脑(177)
心情(181)
天影(25)
乱弹(211)
博客(82)
音乐(18)
饕餮(30)
读书(20)
电影(28)
网摘(5)
希望(37)
汕头(10)
经济(8)
苹果(19)
跋涉(7)



Archive
2008年11月
2008年10月
2008年9月
2008年8月
2008年7月
2008年6月
2008年5月
2008年4月
2008年3月
2008年2月
2008年1月
2007年12月
2007年11月
2007年10月
2007年9月
2007年8月
2007年7月
2007年6月
2007年5月
2007年4月
2007年3月
2007年2月
2007年1月
2006年12月
2006年11月
2006年10月
2006年9月
2006年8月
2006年7月
2006年6月
2006年5月
2006年4月
2006年3月
2006年2月
2006年1月
2005年12月
2005年11月
2005年10月
2005年9月
2005年8月
2005年7月
2005年6月
2005年5月
2005年4月
2005年3月
2005年2月
2005年1月
2004年12月
2004年11月
2004年10月
2004年9月
2004年8月
2004年7月
2004年6月
2004年5月
2004年4月
2004年3月
2004年2月
2004年1月
2003年12月



My Links
5G
bloglines
时尚摄影师奇科的博客
颜如玉
最爱卫斯理

RSS 2.0

Username:
Password:
 Remember me