字符串的哈希值具有特定长度

时间:2008-10-07 06:13:35

标签: c++ algorithm hash

有没有办法生成字符串的哈希,以便哈希本身具有特定的长度?我有一个生成41字节哈希值(SHA-1)的函数,但我需要它最多33个字节(由于某些硬件限制)。如果我将41字节的哈希截断为33,我可能(当然!)失去了唯一性。

或者实际上我认为MD5算法非常合适,如果我能在你的帮助下找到一些C代码。

编辑:谢谢大家的快速和知识渊博的回复。我选择使用MD5哈希,它适合我的目的。唯一性是一个重要问题,但我不认为这些哈希的数量在任何给定时间都非常大 - 这些哈希代表家庭局域网上的软件服务器,因此最多可能有5个,也许10个运行。 / p>

9 个答案:

答案 0 :(得分:6)

  

如果我将41字节的哈希截断为33,我可能(当然!)失去了唯一性。

是什么让你觉得你现在有独特性?是的,当你只用33个字节而不是41个字节时,显然有更高的碰撞几率,但是你需要充分意识到,对于任何使用哈希都有意义的情况,碰撞是不可能的,而不是不可能的。首先。如果您正在散列超过41个字节的数据,那么显然有更多可能的组合,而不是可用的哈希值。

现在,无论你最好截断SHA-1哈希还是使用更短的哈希,比如MD5,我都不知道。我认为在保留整个散列时我会更加自信,但MD5有known vulnerabilities,这可能会或可能不会成为您特定应用的问题。

答案 1 :(得分:5)

计算哈希的方式,遗憾的是不可能。要将散列长度限制为33个字节,您必须将其删除。您可以xor第一个和最后33个字节,因为这可能会保留更多信息。但即使有33个字节,你也没有那么大的碰撞机会。

md5:http://www.md5hashing.com/c++/

顺便说一句。 md5是16个字节,sha1是20个字节,sha256是32个字节,但是作为十六进制字符串,它们的大小都是双倍的。如果你可以存储字节,你甚至可以使用sha256。

答案 2 :(得分:4)

由于设计了哈希算法的方式(熵在结果字符串中均匀分布),因此与子字符串(sha_hash,0,33)冲突的可能性不会超过33字节长的任何其他哈希。

答案 3 :(得分:3)

您可以使用Elf hash(包括<-C代码)或其他一些简单的哈希函数代替MD5或SHA-X。 它们不安全,但可以调整到你需要的任何长度

答案 4 :(得分:2)

根据定义,哈希仅对少量数据是唯一的(即便如此,它仍然无法保证)。由于您无法通过物理方式去除信息并在以后将其恢复,因此无法将大量信息唯一地映射到少量信息。请记住,这不是压缩。

就个人而言,在这种情况下,我会使用MD5(如果你需要存储在文本中),或者使用256b(32B)哈希,例如SHA256(如果你可以存储在二进制文件中)。将另一个散列算法截断为33B也可以,并且可能会增加生成散列冲突的可能性。这取决于算法。

Also, yet another C implementation of MD5, by the people who designed it.

答案 5 :(得分:1)

我相信MD5哈希算法会得到一个32位的数字,所以也许这个算法会更合适。

编辑:要访问MD5功能,应该可以挂钩到openssl库。但是你提到了硬件限制,所以在你的情况下这可能是不可能的。

答案 6 :(得分:1)

33字节冲突的可能性是1/2 ^ 132(生日悖论)

所以不要担心失去独特性。

更新:我没有检查SHA1的实际字节长度。这是相关的计算:32个半字节冲突(33个字节的十六进制 - 1个终止字符),仅当字符串散列数变为sqrt(2 ^(32 * 4))= 2 ^ 64时才会发生。

答案 7 :(得分:1)

Here是C中的MD5实现。

答案 8 :(得分:0)

使用Apache的DigestUtils:

http://commons.apache.org/codec/api-release/org/apache/commons/codec/digest/DigestUtils.html#md5Hex(java.lang.String)

将散列转换为32个字符的十六进制字符串。