不同的文本但是同样的CRC校验和?

4

我的应用程序使用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"));       
}

4
哈希码或CRC校验和并不是唯一的标识符。它们不能是唯一的,参见【鸽笼原理】(http://zh.wikipedia.org/wiki/鸽巢原理)。 - Jesper
3个回答

13

是的,这就是CRC(循环冗余校验)的特点。它们不是唯一的ID,对于不同的输入,它们可能不同,但它们不必如此。毕竟,您提供的输入超过32位,因此您不能期望有超过2 32 不同的输入会产生不同的CRC。

较长的加密哈希值(例如SHA-256)更有可能为不同的输入提供不同的输出,但这仍然不是不可能的(由于输入数据与输出数据的数量差异)。 CRC和加密哈希的重大区别在于,如果需要,可以相对容易地“操纵”CRC - 找到碰撞并不是非常困难,它用于防止意外数据损坏。而加密哈希旨在通过某些攻击者故意数据损坏来保护数据,因此很难故意创建针对特定哈希的值。

顺便说一下,使用String.getBytes()而未指定字符集是有问题的 - 它使用平台默认编码,因此如果在两台具有相同输入的计算机上运行相同的代码,则可能会得到不同的结果。我强烈建议您使用固定编码(例如UTF-8)。


6

是的,它们可以相同,但这只会在非常低的概率2-32下偶然发生。

正如Jon所指出的那样,您可以有意地构建具有相同CRC的字符串。我的欺骗代码可以自动化这一过程。以下是另一个与问题中提供的字符串具有相同CRC的示例,但与第一个字符串存在有限差异: b5a7b702ab643f7ac47fb57c4fb28b82 ,该示例使用欺骗生成。


2

发现具有相同CRC32的2个不同文件/字符串/数据是正常的。因为只有32位,所以使用MD5/SHA1-512可以更好地防止重复。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接