好的,只能使用64位的sha1哈希作为id?

时间:2009-04-16 03:31:01

标签: hash sha1

1)为了实现真正的低哈希冲突,我是否可以使用sha1的128位中的一半而不是处理sha1本身?我知道这不适用于加密哈希,但我只需要哈希表键的哈希值。

2)计算时间不是优先考虑的事项,除此之外我还要挖掘非常小的数据。特别是,我主要是采用2或3个64位哈希并对它们进行散列以获得另一个64位哈希值。为此目的,有比sha1更好的选择吗?同样,碰撞应该是不太可能的。

3)我是一个sql newb。在sql中使用64位哈希作为id是一个好主意吗? 64位id是否会导致sqlite或postgres出现性能问题?我将需要跨多个数据库协调数据(包括Lucene索引),所以我认为我应该直接在表中处理哈希,而不是打扰自动递增的id(这只会在一个数据库中有意义,而不是跨所有数据存储)。我认为64位是一个很好的折衷方案:足够大,不可能发生冲突但节省空间(和查询时间?)。

4)CRC-64怎么样?这会产生足够随机的分布吗?

5 个答案:

答案 0 :(得分:6)

如果你的记录足够少,几乎可以肯定你永远不会有64位的哈希冲突。可能你会属于这一类。

应该修剪像sha1这样的加密哈希是没有问题的,因为如果哈希中有内部结构那么它就不足以成为加密哈希,如果有的话没有结构,那么比特的任何子集应该是非常随机的。请注意,我只是讨论将其用于ID,而不是用于任何加密目的!

但实际上,你的SQL是不是有某种GUID?如果确实如此,为什么不使用它?

答案 1 :(得分:4)

为了更好地比较哈希的长度,请查看http://en.wikipedia.org/wiki/List_of_hash_functions

另外,只需注意:SHA-1是160位,而不是128位。

答案 2 :(得分:3)

您的密钥需要绝对唯一性,而不是唯一性的高概率。我建议使用GUID而不是哈希来为您的密钥提供跨数据库兼容性。生成哈希作为快速查找机制 - 您可以对此进行非唯一索引 - 但在发生冲突时,您必须比较实际数据以确保它们是相同的。在同步数据库时,您可以检查哈希值(快速使用索引),如果发现冲突,则解决数据是否相同,因此需要解析GUID。如果没有冲突,则只需更新缺少条目的数据库,然后使用其他数据库中的GUID进行插入。

我也是,在创建自己的哈希散列以节省空间方面没什么意义。如果你已经有其他哈希值,只需使用它们(追加,不要重新散列)。如果没有,只需使用标准哈希函数,如MD5或SHA1,并存储结果数据。

答案 3 :(得分:2)

对于64位哈希,您有1%的机会与6.1×10 8 记录发生冲突。 (对于其他组合,请参阅Wikipedia的page on the Birthday problem。)您可以丢弃每秒的前64位或最后一位,它对哈希的属性没有任何影响。

答案 4 :(得分:0)

如果计算时间不重要,为什么不去整个128位呢?除了可能的存储问题之外,有没有真正的理由选择64位? (然后额外的8个字节不会因为存储如此便宜而杀死你)

64位与128位将导致SQLite没有速度问题,我不确定mySQL。