散列不太长的字符串向量(urls)的最佳方法是什么?

时间:2011-04-20 20:30:17

标签: c++ hash

我现在正在处理网址分类。我用“/?”等分区url,生成一堆部分。在这个过程中,我需要将第一部分哈希到第k部分,比如k = 2,然后对于“http://stackoverflow.com/questions/ask”,键是一个字符串向量“stackoverflow.com questions” 。目前,哈希就像哈希。但它消耗了大量的内存。我想知道MD5是否可以提供帮助,还是有其他选择。实际上,只要区分不同的密钥,我就不需要准确地恢复密钥。 谢谢!

3 个答案:

答案 0 :(得分:1)

  

消耗大量内存

如果您的代码已经运行,您可能需要考虑将其保留原样。如果你没有目标,你就不知道什么时候完成。在你的案例中,你确定“很多”是“太多”的同义词吗?

如果您确定需要更改工作代码,则应考虑可用的各种选项,而不是将某人用于特定算法:

不确定内存含义,它肯定会改变你的穿孔轮廓,但你也可以考虑使用Tries:

http://en.wikipedia.org/wiki/Trie

答案 1 :(得分:1)

对于安全性不是问题的东西,MD5是一个很好的哈希代码。它速度快而且相当长(128位足以满足大多数应用)。分布也非常好。

Adler32可能是另一种选择。它很容易实现,只需几行代码。它比MD5更快。对于许多应用程序而言,它足够长/足够好(尽管对许多应用程序来说不是这样)。 (我知道Adler32严格来说不是哈希码,但它对许多应用程序仍然可以正常运行)

但是,如果存储哈希代码占用大量内存,则可以始终截断哈希代码,或使用XOR“缩小”它。 E.g。

uint8_t md5[16];
GetMD5(md5, ...);

// use XOR to shrink the MD5 to 32 bits
for (size_t i = 4; i < 16; i++)
    md5[i % 4] ^= md5[i];

// assemble the parts into one uint32_t
uint32_t const hash = md5[0] + (md5[1] << 8) + (md5[2] << 16) + (md5[3] << 24);

我个人认为MD5会有点矫枉过正。看看Adler32,我认为它会做。


修改

我必须纠正自己:对于短字符串(少于几千字节),Adler23是一个相当糟糕的选择。我完全忘了这件事。但总有一个显而易见的事:CRC32。没有Adler23那么快(与MD5的速度大致相同),但仍然可以轻松实现,并且还有大量现有的实施,包含各种许可证。

答案 2 :(得分:0)

如果您只是想知道两个URL是否相同,您是否考虑过存储服务器IP地址的二进制版本?如果两个服务器名称解析为相同的地址是不正确的还是应用程序的优势?