我的应用程序使用CRC32检查两个内容或两个文件是否相同。 但是当我尝试使用它来生成唯一的id时,我看到了问题,使用两个不同的字符串,CRC32可以是相同的。这是我的Java代码。提前谢谢。
public static String getCRC32(String content) {
byte[] bytes = content.getBytes();
Checksum checksum = new CRC32();
checksum.update(bytes, 0, bytes.length);
return String.valueOf(checksum.getValue());
}
public static void main(String[] args){
System.out.println(getCRC32("b5a7b602ab754d7ab30fb42c4fb28d82"));
System.out.println(getCRC32("d19f2e9e82d14b96be4fa12b8a27ee9f"));
}
答案 0 :(得分:11)
是的,这就是CRC的样子。他们不是唯一ID。对于不同的输入,他们可能会有所不同,但他们 。毕竟,您提供超过32位的输入,因此您不能期望有超过2个 32 不同的输入,以产生不同的CRC。
较长的加密哈希(例如SHA-256)很可能为不同的输入提供不同的输出,但它仍然不是不可能的(并且不可能,由于输入数据量与输出数据量的关系)。 CRC和加密哈希之间的最大区别在于CRC相对容易引导"转向"如果您愿意 - 发现冲突并不是非常困难,并且它用于防止意外数据损坏。加密哈希旨在防止某些攻击者故意数据损坏 - 因此很难故意创建针对特定哈希的值。
顺便说一下,使用String.getBytes()
而不指定字符集是有问题的 - 它使用平台默认编码,因此如果您在具有相同输入的两台计算机上运行相同的代码,则可以获得不同的结果。我强烈建议您使用固定编码(例如UTF-8)。
答案 1 :(得分:5)
是的,它们可以是相同的,但这种情况会偶然发生,概率很低,只有2 -32 。
Jon指出,你可以故意构造具有相同CRC的字符串。 My spoof code自动执行此操作。下面是另一个字符串的示例,该字符串与问题中显示的CRC具有相同的CRC,但与第一个字符串的差异有限:b5a7b702ab643f7ac47fb57c4fb28b82
,使用欺骗生成。
答案 2 :(得分:2)
使用相同的CRC32找到2个不同的文件/字符串/数据是正常的。只有32位。使用MD5 / SHA1-512可以更好地防止重复。