具有顺序保留的哈希函数

时间:2015-01-20 11:10:01

标签: algorithm sorting hash

是否有任何带有uniq哈希码的哈希函数(如MD5)和命令保留?

注意: 我不关心安全性,我需要它进行排序,我有很多块(~1MB大小),我想对它们进行排序,当然我可以使用索引排序,但我想减少比较时间< / p>

Theoreticaly: 如果我有1&000; 000&#39; 000块大小为1MB(1&#39; 048&#39; 576字节)并且它们在最后10个字节中都有差异,那么一个块与其他块的比较时间将是O (n-10)如果我将使用QuictSort(使〜(n log2(n))比较)那么比较的总时间将是n log2(n)*(k-10)(其中k是块大小) 1&#39; 000&#39; 000 * 20 *(1&#39; 048&#39; 576 - 10)

这就是为什么我想生成具有固定大小(例如16个字节)的订单保留哈希码,然后对块进行排序并保存结果(例如:在文件中)

6 个答案:

答案 0 :(得分:11)

CHM(Z.J. Czech,G.Havas和B.S.Majewski)是一种算法,其产生保持排序的最小完美散列(例如,如果A

请参阅:http://cmph.sourceforge.net/chm.html

答案 1 :(得分:1)

一般情况下,除非哈希的大小至少是对象的大小,否则这样的函数是不可能的。

这个论点是微不足道的:如果有N个对象,但M&lt; N个哈希值,pigeonhole principle,两个不同的对象被映射到一个哈希值,因此它们的顺序不会被保留。

但是,如果我们保证保证对象的其他属性或放宽要求,则可能会有自定义或概率解决方案。

答案 2 :(得分:1)

N个字符串数组进行排序,每个字符串的长度为K,只需O (NK)O (N^2 + NK)字符比较即可完成。

例如,构建一个trie

或者做一种插入排序。通过逐个添加字符串来构造排序字符串S的集合。对于每个新字符串P,遍历它,维护Q中最大字符串S的(非递减)索引,使Q <= P。当字符串P结束时,请在S之后将其插入Q。每个O(N)插入都可以在O(N+K)次操作中完成:O(N)次,将索引分配到K


如果你有按顺序排列的字符串索引,只需将它们用于你的目的而不是&#34;哈希&#34;你想要的。

答案 3 :(得分:0)

根据NIST(我没有专家),Pearson哈希可以保留订单。哈希使用辅助表。这样的表可以(理论上)构造成使得得到的散列是保持顺序的。

但它并不能满足您的全部要求,因为它不会像您希望的那样减小尺寸。我发布这个以防其他人正在寻找解决方案。

一些指示:

答案 4 :(得分:0)

让我们根据需求构造这样的功能:

  1. 您想要一个输出16字节哈希的函数。因此,您将发生碰撞。您无法保持完美的秩序,而且您不想这样做。最好的办法是:

    H(x) x

    H(x)> H(y)=> x> y

彼此接近的值将具有相同的哈希值。

  1. 对于每个x,都有一个i_x> 0,因此H(x) = H(x + i_x) < H(x + i_x + 1)。 (除了x + i_x + 1将溢出您的1MB块的末尾。)

扩展为:H(x) < H(x + i_x + n)代表n > 0

相同的参数在另一个方向上适用于j_x> 0。合并它们,您将得到:

H(x - j_x) == H(x - j_x + 1) == ... == H(x + i_x - 1) == H(x + i_x)

或者换句话说,每个哈希值都有一个映射到相同值的段[a,b]。此段之外的任何值都不能具有相同的哈希值,否则将违反顺序。

您可以通过选择的细分来描述您的哈希函数:

让a_i为带有0 <= i < 256^16a_i <= a_i+1的1MB块。然后

H(x) = i where a_i <= x < a_i+1
  1. 您希望散列值的分布更加不均匀。否则,一个碰撞将比另一个碰撞多得多,并且当达到该值时,您将花费所有时间进行全面比较。因此,所有段[a,b]的大小都应大致相同。

使每个段的大小完全相同的唯一方法是拥有

a_i = i * 2 ^ (1MB - 16)

或换句话说:H(x)= x的前16个字节。

对于任何一组随机输入块,其他任何保留16字节输出的保留哈希函数的效率都会降低。

是的,如果每个输入块的除最后几个比特外的其他所有比特都是相同的,则每个测试都会产生冲突。那是最坏的情况,总是存在。如果您知道输入不是均匀随机的,则可以调整每个段的大小以具有相同的命中概率。但这需要了解可能的输入。

注意:如果您真的想对1,000万个1MB的块进行排序,而您担心这种情况最坏的情况,则可以使用存储桶排序,结果每次比较1,000,000 * 1'048'576(字节)。如果一次比较16位值(其中的桶数仍然合理,则为一半)(65536)。

答案 5 :(得分:-2)

理论上没有这样的事情。如果需要,可以创建组合哈希:

  

指数:MD5

我认为这将解决您的需求。