指定长度的字符串的哈希
Hash of a string to be of specific length
有没有一种方法可以生成字符串的哈希,使哈希本身具有特定的长度?我有一个生成41字节散列(SHA-1)的函数,但我需要它最大为33字节(因为某些硬件限制)。如果我将41字节的散列截断为33,我可能(当然!)会失去唯一性。
或者实际上,如果我能在你的帮助下找到一些C代码,我想MD5算法会很合适。
编辑:感谢大家的快速和知识渊博的回复。我选择了MD5散列,它非常适合我的目的。唯一性是一个重要的问题,但我不认为这些哈希的数量在任何给定的时间都会很大——这些哈希代表家庭局域网上的软件服务器,所以最多会有5个,也许10个在运行。
如果我将41字节的散列截断为33,我可能(当然!)会失去唯一性。
是什么让你觉得自己现在很独特?是的,当你只使用33个字节而不是41个字节时,显然发生冲突的几率更高,但你需要充分意识到,对于任何首先使用哈希有意义的情况,冲突都是不可能的。如果你对超过41字节的数据进行散列,那么可能的组合显然比可用的散列更多。
现在,我不知道是截断SHA-1哈希还是使用MD5之类的较短哈希更好。我想我在保存整个哈希时会更有信心,但MD5有已知的漏洞,这些漏洞可能对您的特定应用程序有问题,也可能不是问题。
不幸的是,哈希的计算方式是不可能的。为了将哈希长度限制在33个字节,你必须将其剪切。你可以对第一个和最后33个字节进行异或,因为这可能会保留更多的信息。但是,即使有33个字节,发生冲突的可能性也不大。
md5:http://www.md5hashing.com/c++/
顺便说一句。md5是16字节,sha1是20字节,sha256是32字节,但是作为六进制字符串,它们的大小都是原来的两倍。如果你可以存储字节,你甚至可以使用sha256。
由于哈希算法的设计方式(熵在生成的字符串中均匀分布),与子字符串(sha_hash,0,33)碰撞的可能性不比与任何其他33字节长的哈希碰撞的可能性大。
您可以使用Elf散列(包括<-C代码)或其他类似的简单散列函数来代替MD5或SHA-X。它们不安全,但可以调整到您需要的任何长度
/*****Please include following header files*****/
// string
/***********************************************/
/*****Please use following namespaces*****/
// std
/*****************************************/
static unsigned int ELFHash(string str) {
unsigned int hash = 0;
unsigned int x = 0;
unsigned int i = 0;
unsigned int len = str.length();
for (i = 0; i < len; i++)
{
hash = (hash << 4) + (str[i]);
if ((x = hash & 0xF0000000) != 0)
{
hash ^= (x >> 24);
}
hash &= ~x;
}
return hash;
}
示例
string data = "jdfgsdhfsdfsd 6445dsfsd7fg/*/+bfjsdgf%$^";
unsigned int value = ELFHash(data);
输出
248446350
Hashes根据定义仅对少量数据是唯一的(即使这样也不能保证)。不可能将大量信息唯一地映射到少量信息,因为你不能从语法上去除信息,然后再把它拿回来。请记住,这不是压缩正在进行。
就我个人而言,在这种情况下,我会使用MD5(如果你需要以文本形式存储),或者256b(32B)哈希,比如SHA256(如果你可以以二进制形式存储)。将另一个哈希算法截断到33B也可以,并且可能会增加生成哈希冲突的可能性。这在很大程度上取决于算法。
此外,MD5的另一个C实现,由设计人员完成。
我相信MD5哈希算法会产生一个32位数的数字,所以这个数字可能更合适。
编辑:要访问MD5功能,应该可以挂接到openssl库中。然而,您提到了硬件限制,因此在您的情况下这可能是不可能的。
这里是C.中的MD5实现
33字节冲突的几率是1/2^132(根据生日悖论)
所以不要担心失去独特性。
更新:我没有检查SHA1的实际字节长度。以下是相关的计算:只有当散列的字符串数量变为sqrt(2^(32*4))=2^64左右时,才会发生32个半字节的冲突(33字节的十六进制-1终止字符)。
使用Apache的DigestUtils:
http://commons.apache.org/codec/api-release/org/apache/commons/codec/digest/DigestUtils.html#md5Hex(java.lang.String)
将哈希转换为32个字符的十六进制字符串。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 如何为字符串生成唯一但一致的 N 位哈希(小于 64 位)?
- 对于短字符串来说,这是一个很好的哈希函数吗?
- 我的求解(字符串 a、字符串 b)的输出与随机哈希中的预期输出不匹配
- 我可以比朴素哈希表更快地将随机字符串映射到两个类吗?
- 自定义哈希表实现-将字符串映射到整数时出现内存错误
- 在 cpp 自己的版本中对字符串进行哈希处理
- 哈希字符串更改大小写
- 以字符串向量作为值的哈希映射
- 字符串单词的唯一哈希值
- 用于对编译时字符串进行哈希处理的延迟指针
- 如何生成伪随机 32 字节字符串以用作加密哈希函数中的盐?
- 在哈希表中调整字符串数组的大小
- C 字符串哈希散列字符串或内存地址吗?
- 有关忽略字符顺序的字符串哈希函数的建议
- 适用于短文件名的最佳字符串哈希函数
- 此示例的最佳字符串哈希函数
- 使用异或和位移位的字符串哈希算法
- 在哈希表中创建字符串哈希值的时间复杂度
- 在C++中真正编译时字符串哈希