PHP CRC32为两个不同的字符串提供相同的整数值

PHP CRC32为两个不同的字符串提供相同的整数值,php,crc32,Php,Crc32,我正在使用PHP的crc32函数为MongoId生成数字等价物,因为我在mysql搜索中使用这个数字id,因为字符串搜索很慢 我遇到了一个案例,crc32为两个不同的mongoid提供相同的数值 如有任何帮助或建议,将不胜感激 谢谢 Gaurav除非您的字符串是四个字节或更少,否则许多字符串将不可避免地具有任何给定的CRC-32值。如果您甚至只有一个多于2^32的可能字符串,那么绝对可以保证至少有两个字符串将映射到同一个CRC-32 没有任何帮助或建议。除非可能的字符串少于可能的CRC,否则不能

我正在使用PHP的crc32函数为MongoId生成数字等价物,因为我在mysql搜索中使用这个数字id,因为字符串搜索很慢

我遇到了一个案例,crc32为两个不同的mongoid提供相同的数值

如有任何帮助或建议,将不胜感激

谢谢
Gaurav

除非您的字符串是四个字节或更少,否则许多字符串将不可避免地具有任何给定的CRC-32值。如果您甚至只有一个多于2^32的可能字符串,那么绝对可以保证至少有两个字符串将映射到同一个CRC-32

没有任何帮助或建议。除非可能的字符串少于可能的CRC,否则不能期望没有冲突


顺便说一句,您可以使用my故意构造这样的事例,它允许您给它一组允许在字符串中更改的位,它将告诉您要翻转这些位中的哪一位以获得所需的CRC。

@MarkAdler的回答解释了为什么会出现哈希冲突。但如果我处在你的位置,我会对我能做些什么更感兴趣

当然,您可以使用不同的散列算法,生成更长的散列(冲突的可能性更小),但速度仍然可以接受。您将在from programmers.stackexchange.com中找到对几种备选方案的高度评价。它们都有碰撞(巧合的是,CRC32在该答案的测试集中表现得相当不错),但您可以在Mongoid上尝试其中一些,看看会发生什么

我还发现:要生成64位散列,可以采用两种不同的32位散列算法并连接散列(当然,这将或多或少降低散列速度的一半)

更健壮的解决方案是在编写代码时理解散列是一个bucket,有时会从crc32查询中得到多个结果(或错误的结果)。只需添加第二步来检查返回记录的未删除Id。因为只会有少量的点击,所以不会花很长时间。

这可能是相关的