如果我有由字符(a到z和。)组成的字符串L,即总共27个字符,每个字符串最大可以包含256个字节。我可以使用具有0次冲突的哈希函数(实际上,理论上不是这样)吗?完美的哈希函数在这里不起作用,因为L可以被修改(即它不仅仅是只读的)
我只对实际的东西感兴趣。我知道不可能生成0次冲突的哈希函数。
我可以使用md5sum,但这会生成一个16字节的整数。我只是想寻找一个4字节或最大8字节的整数。
有可能吗?
感谢您的耐心
〜GC〜
答案 0 :(得分:2)
一种解决方案:只需使用MD5之类的已知哈希函数,并使用最低的4或8字节。
答案 1 :(得分:1)
其他人已经建议了正确的解决方案(使用哈希值),但是如果你真的对尽可能少的碰撞感兴趣,那么有两个想法可以更大规模地考虑这个问题:
如果您在内存中保存了一些(或所有)要生成ID的字符串,则可以使用存储字符串的内存地址作为ID。假设就地更改字符串是可以的,这个ID甚至会在字符串更改时保持稳定。
使用一些简单的压缩系统(例如miniLZO)将列表中的字符串压缩为某种内部表示可能是切实可行的。最终可能会有更少的数据要散列,因此可能有更简单的散列函数。当然,以这种方式计算哈希值更加昂贵,但您可以避免冲突。
答案 2 :(得分:0)
某种校验和或哈希 是正确的答案。
你是对的,你无法避免碰撞。但是如果你将校验和或哈希缩短到只有4个字节,那么冲突的频率将会大幅增加。
如果没关系,你可以查看http://en.wikipedia.org/wiki/Hash_function之类的内容,找到一个你觉得舒服的东西。
答案 3 :(得分:0)
由于您的数据有限,您可以使用它来指导散列。
假设字符串是以nul结尾的ASCII,您可以从映射到一个小整数开始。
char *charset = "abcdefghijklm"
"nopqrstuvwxyz.";
int c = strchr(charset, *s++) - charset;
然后,将每个值视为基数-27基数。在从当前字符添加0-26“单位”之前,将总和乘以27进行解码。你提到一个最大长度。我猜这意味着字符串存储在固定长度的数组中。如果是这样的话,阵列不仅仅是nul-terminated,而是nul-padded。那么你可以向后解码数组,以便在基数为27的数字的最低有效“位置”中存在显着差异。但是如果大小只是一个慷慨的高估,并且大多数字符串预计要短得多,那么向前扫描并在nul上终止可能会更好。
int sum;
sum *= 27;
sum += c;