我知道原始 md5 算法会生成 128 位哈希值。
关注 Mark Adler 的评论 here我有兴趣获得一个好的 64 位哈希值。 有没有办法使用 OpenSSL 创建基于 md5 的 64 位哈希? (md5 看起来足以满足我的需要)。 如果没有,OpenSSL 库中是否有另一种算法可以以不低于 md5 的质量完成这项工作(当然长度除外)?
最佳答案
我声称,“哈希质量”与哈希长度密切相关。 AFAIK,OpenSSL 没有 64 位哈希算法,所以我的第一个想法很简单,而且很可能毫无值(value):
halfMD5 = md5.hiQuadWord ^ md5.lowQuadWord
最后,我只需使用具有适当输出的算法,例如 crc64。
一些需要验证的 crc64 源:
编辑
At first glanceת Jenkins looks perfect, however I'm trying to find a friendly c++ implementation for it without luck so far. BTW, I'm wondering, since this is such a good hash for databases' duplication checking, how come that non of the common opensource libraries, like OpenSSL, provides an API of it? – Subway
这可能只是因为 OpenSSL 首先是一个加密库,使用具有适当加密特征的大哈希值。
数据结构的哈希算法还有一些其他主要目标,例如哈希表具有良好的分布特征,其中小的哈希值用作包含零个、一个或多个(冲突)元素的存储桶列表的索引。
所以重点是是否、如何以及在何处处理冲突。 在典型的 DBMS 中,列上的索引将自行处理它们。
相应的容器( map 或集合):
C++:
std::size_t
(32 或 64 位)对于std::unordered_multimap
和std::unordered_multiset
在 java 中,可以使用列表作为存储桶进行映射:
HashMap<K,List<V>>
唯一约束将另外禁止插入相同的字段内容:
C++:
std::size_t
(32 或 64 位)对于std::unordered_map
和std::unordered_set
例如,我们有一个表,其中包含文件内容(明文、非加密应用程序)以及用于映射或一致性检查的校验和或哈希值。我们要插入一个新文件。为此,我们预先计算哈希值或校验和,并分别查询具有相等哈希值或校验和的现有文件。如果不存在,则不会发生碰撞,插入将是安全的。如果存在一条或多条现有记录,则完全匹配的概率较高,“真实”冲突的概率较低。
如果应忽略冲突,可以向散列列添加唯一约束并重用可能存在不匹配/冲突内容的现有记录。在这里,您需要一个像“Jenkins”这样的数据库友好的哈希算法。
如果需要处理冲突,可以向明文列添加唯一约束。对数据库不太友好的校验和算法(例如 crc)不会对记录之间的冲突产生影响,并且可以根据要检测的某些类型的损坏或其他要求进行选择。甚至可以使用开头提到的 md5 的异或四字。
其他一些想法:
- 如果明文列上的索引/约束进行映射,则任何哈希值都可用于进行相当快速的查找以查找潜在的匹配项。
- 没有人会阻止您添加映射友好的哈希值和校验和。
- 唯一约束还会添加索引,基本上类似于上面提到的哈希表。
简而言之,这很大程度上取决于您想要使用 64 位哈希算法实现什么目标。
关于C++ OpenSSL : md5-based 64-bits hash,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15459321/