为字符串生成唯一的整数(4个字节或8个字节)

时间:2011-06-29 06:56:26

标签: c

如果我有由字符(a到z和。)组成的字符串L,即总共27个字符,每个字符串最大可以包含256个字节。我可以使用具有0次冲突的哈希函数(实际上,理论上不是这样)吗?完美的哈希函数在这里不起作用,因为L可以被修改(即它不仅仅是只读的)

我只对实际的东西感兴趣。我知道不可能生成0次冲突的哈希函数。

我可以使用md5sum,但这会生成一个16字节的整数。我只是想寻找一个4字节或最大8字节的整数。

有可能吗?

感谢您的耐心

〜GC〜

4 个答案:

答案 0 :(得分:2)

一种解决方案:只需使用MD5之类的已知哈希函数,并使用最低的4或8字节。

答案 1 :(得分:1)

其他人已经建议了正确的解决方案(使用哈希值),但是如果你真的对尽可能少的碰撞感兴趣,那么有两个想法可以更大规模地考虑这个问题:

  1. 如果您在内存中保存了一些(或所有)要生成ID的字符串,则可以使用存储字符串的内存地址作为ID。假设就地更改字符串是可以的,这个ID甚至会在字符串更改时保持稳定。

  2. 使用一些简单的压缩系统(例如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;