针对我们的每个二进制资产,我们会生成一个MD5哈希值。这被用来检查特定的二进制资产是否已经存在于我们的应用程序中。但是,不同的二进制资产是否可能生成相同的MD5哈希值?因此,不同的字符串是否可能生成相同的MD5哈希值?
针对我们的每个二进制资产,我们会生成一个MD5哈希值。这被用来检查特定的二进制资产是否已经存在于我们的应用程序中。但是,不同的二进制资产是否可能生成相同的MD5哈希值?因此,不同的字符串是否可能生成相同的MD5哈希值?
MD5是一种加密哈希函数 - 因此,两个不同的字符串可以生成相同的MD5代码。
特别地,需要注意的是,MD5代码具有固定长度,因此可能的MD5代码数量是有限的。然而,任意长度的字符串数量绝对是无限的,因此逻辑上一定会发生碰撞。
$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c6b384c4968b28812b676b49d40c09f8af4ed4cc -
008ee33a9d58b51cfeb425b0959121c9
$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c728d8d93091e9c7b87b43d9e33829379231d7ca -
008ee33a9d58b51cfeb425b0959121c9
$ diff -u <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2 | fold -w2) <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2 | fold -w2)
--- /dev/fd/63 2016-02-05 12:55:04.000000000 +0000
+++ /dev/fd/62 2016-02-05 12:55:04.000000000 +0000
@@ -33,7 +33,7 @@
af
bf
a2
-00
+02
a8
28
4b
@@ -53,7 +53,7 @@
6d
a0
d1
-55
+d5
5d
83
60
另一个测试:
$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
756f3044edf52611a51a8fa7ec8f95e273f21f82 -
cee9a457e790cf20d4bdaa6d69f01e41
$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
6d5294e385f50c12745a4d901285ddbffd3842cb -
cee9a457e790cf20d4bdaa6d69f01e41
SHA-1校验和不同,但MD5哈希值相同。
区别在于一个字节:
$ diff -u <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2) <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2)
--- /dev/fd/63 2016-02-05 12:56:43.000000000 +0000
+++ /dev/fd/62 2016-02-05 12:56:43.000000000 +0000
@@ -19,7 +19,7 @@
03
65
9e
-70
+74
4f
85
34
@@ -41,7 +41,7 @@
a3
f4
15
-5c
+dc
bb
86
07
上面的例子改编自Tao Xie和Dengguo Feng: 使用仅一个消息块构造MD5碰撞, 2010年。
相关:
当然可以:MD5哈希具有有限长度,但是可以对无限数量的字符字符串进行MD5哈希。
我认为根据我们的需求仔细选择哈希算法是必要的,因为哈希冲突并不像我想象的那样稀有。最近我在我的项目中发现了一个非常简单的哈希冲突案例。我正在使用 xxhash 的 Python 封装进行哈希。链接:https://github.com/ewencp/pyhashxx
s1 = 'mdsAnalysisResult105588'
s2 = 'mdsAlertCompleteResult360224'
pyhashxx.hashxx(s1) # Out: 2535747266
pyhashxx.hashxx(s2) # Out: 2535747266
这在系统中引起了非常棘手的缓存问题,最终我发现这是哈希碰撞。
是的,这是可能发生的(尽管风险非常小)。否则,你会有一个相当有效的压缩方法!
编辑:正如Konrad Rudolph所说:将潜在无限的输入转换为有限的输出集(32个十六进制字符)将导致无数次碰撞。