字节数组的重叠子数组是否足够独立,可用作Bloom Filter的哈希函数?

时间:2011-07-11 20:30:33

标签: statistics correlation bloom-filter

我在BloomFilter的上下文中有以下问题。 BloomFilters需要具有k个独立的哈希函数。我们称这些函数为h1, h2, ... hk。在这种情况下独立意味着当应用于同一组时,它们的值将具有非常小的相关性(希望为零)。请参阅http://en.wikipedia.org/wiki/Bloom_filter处的算法说明(当然,您已经知道该页面内外了:)。

现在,假设我想使用一些n位(来自加密函数,如果您必须知道,但它与问题无关)来定义我的散列函数,它们彼此独立。如果你想要更多的上下文,你可以阅读http://bitworking.org/news/380/bloom-filter-resources做类似的事情。

例如,假设我想将每个h定义为(原谅我的伪代码):

bytes = MD5(value)
h1 = bytes[0-3] as Integer
h2 = bytes[4-7] as Integer
h3 = bytes[8-11] as Integer
...

当然,我们将很快耗尽哈希函数。我们在这个MD5示例中只获得了四个。

一种可能性是让散列函数相互重叠,并且不要求四个字节是顺序的。这样,我们有许多散列函数作为字节数组允许的排列。为了简单起见,如果我们按以下方式定义哈希函数怎么办:

bytes = MD5(value)
h1 = bytes[0-3] as Integer
h2 = bytes[1-4] as Integer
h3 = bytes[2-5] as Integer
...

很容易看出,在MD5的情况下,我们现在有12个散列函数而不是4个。

最后,我们进入 THE 问题。这些散列函数是独立的吗?谢谢!

更新:我决定尝试从实际的角度回答这个问题,所以我创建了一个小程序来测试这个假设。见下文。

2 个答案:

答案 0 :(得分:0)

通常情况就是聪明的问题,答案是肯定的,不是。

是的,从某种意义上说,在h1和h2之间没有共享16位。不,在对你很重要的意义上(除非你实际上只使用了8位散列函数,我认为你不是这样)。

这里的问题不再是应用于相同项目的两个函数之间的依赖关系以及更多(在这种情况下,在我看来)函数被应用于多个项目。

这样想。假设您的第一个示例使用g1-g4,第二个示例使用h1-h4。 MD5sum(或任何其他散列函数)仅在5个连续字节中重叠的两个项目(不太可能,但在统计上可行,特别是如果你正在尝试)如果只使用h1和h2,h2和h3,将有机会发生冲突,或者h3和h4。同时g1-g4对这种可能性很强。

现在与bloom过滤器的冲突并不像其他哈希函数应用程序那么大,但是你应该记住,重叠的字节确实会减少哈希函数的效用。老实说,我有点惊讶你需要超过四个独立的哈希函数。

另外,如果你只使用每个数字的最后8位(256位布隆过滤器)或最后16位(2 ^ 16位布隆过滤器),或者其他什么,那么你可以'重叠'那些位你没有随意放弃而没有风险。

声明: 我非常了解密码学和绽放过滤器,因为它们非常棒,但我对Bloom过滤器的实际了解有限;你所描述的内容可能对你的用例非常有用。

答案 1 :(得分:0)

运行以下程序将使用随机数生成器测试该假设。

public static void main(String[] args) {
    int R = 100, N = 10000, W = 8;
    double[] totals = new double[33];
    Random r = new Random();

    for (int k = 0; k < R; k++) {
        // Generate 10,000 random byte arrays
        byte[][] bytes = new byte[N][W];
        for (int i = 0; i < N; i++) r.nextBytes(bytes[i]);

        double[] a1 = new double[N], a2 = new double[N];
        for (int i = 0; i <= 32; i++) {

            // Extract arrays
            for (int j = 0; j < N; j++) {
                a1[j] = readInt(bytes[j], 0, 31);
                a2[j] = readInt(bytes[j], 32 - i, 31);
            }

            double c = (new PearsonsCorrelation()).correlation(a1, a2);
            totals[i] += c;
        }
    }
}

有趣的是,只有当只有一个重叠位时,相关才开始显着。下面是每个重叠位数的皮尔森相关系数。我们开始时非常低(意味着接近0重叠的情况),并在完全重叠时获得1

0   -0.001883705757299319
1   -0.0019261826793995395
2   -0.0018466135577488883
3   -0.001499114477250019
4   -0.0010874727770462341
5   -1.1219111699336884E-5
6   -0.001760700583842139
7   3.6545455908216937E-4
8   0.0014823972050436482
9   0.0014809963180788554
10  0.0015226692114697182
11  0.00199027499920776
12  0.001720451344380218
13  -2.0219121772336676E-4
14  6.880004078769847E-4
15  8.605949344202965E-4
16  -0.0025640320027890645
17  -0.002552269654230886
18  -0.002550425130285998
19  -0.002522446787072504
20  -0.00320337678141518
21  -7.554573868921899E-4
22  -6.463448718890875E-4
23  -3.4709181348336335E-4
24  0.0038077518094915912
25  0.0037865326140343815
26  0.0038728464390708982
27  0.0035091958914765407
28  0.005099109955591643
29  0.016993434043779915
30  0.06120260114179265
31  0.25159073855202346
32  1.0

底线:对于哈希函数生成,似乎一个字节的移位(意味着上面的24值)应该是非常安全的。