基数为2的整数最小完美哈希

时间:2016-09-22 00:06:59

标签: c hash integer range perfect

我在一个简单的哈希函数之后,它会将一个基数为2的范围内的整数和(随机)哈希值转换到该范围内的另一个整数而不会发生冲突。这将用于构建置换,并且优选地从种子值构建置换。所以只是抵消整数和调制不起作用。有人知道用C写的好选项吗?

谢谢, 约什

1 个答案:

答案 0 :(得分:1)

这可能有所帮助(有关更一般的方法,请参阅底部):multiplicative cyclic groups允许您选择k“种子”值,n“最大”值,以及以非常有效的方式将自然数从零到n-1置换(k可以在Z中,但最好是两个自然数)。唯一的问题,如果你想要一个排列,那就是n必须是素数,我不确定所有的排列是否均匀分布在种子空间周围(关于cryptography的一些知识会在这里帮忙很多)。

主要操作将是这样的,在伪代码中:

for i in range(0, n){ i:= (i*k)(mod n);}

这里有一个C语言中的玩具程序:

#include <stdio.h>

int main(void)
{
  // take a prime number (from https://primes.utm.edu/lists/2small/0bit.html)
  //int n = (int)pow(2,13)-1;
  // for the sake of test, let's take a little one:
  int n = 23;
  // take a random integer seed:
  int k = 1234;
  printf("permutation of numbers from 0 below %d with seed %d:\n", n, k);
  for (int i=0; i<n; i++){
    printf("%d ", ((i*k)%n));
  }
  printf("\n");
  return 0;
}

返回:

permutation of numbers from 0 below 23 with seed 1234:
0 15 7 22 14 6 21 13 5 20 12 4 19 11 3 18 10 2 17 9 1 16 8 

这不完全是你想要的,但通过一些调整它可以正常工作......除非我们谈论高端安全性的东西。可能最直接的解决方案是选择接近2的幂的素数,并做一些调整? https://primes.utm.edu/lists/2small/

让我知道它是否有帮助!

编辑我无法在我的emacs上直接测试它,所以这是后人的功能:

(defun permute (n seed)
  "prints a permutation of the set of numbers between 0 and n-1, 
   provided n is prime"
  (let ((permuted (loop for i below n collect (% (* i seed) n))))
    (print permuted)
    ;(print (sort permuted '<)) ; debug print
    ))

(test 23  1234) ; returns (0 15 7 22 14 6 21 13 5 20 12 4 19 11 3 18 10 2 17 9 1 16 8)

编辑2 实际上,如Bézout's theorem中所述,kn相互支配就足够了。从技术上讲,如果你确定的话,你可以拥有n的任意自然值。一种直接但有限的方法是从素数列表中随机选择k。一个更好的解决方案是计算每个给定的n它的相对素数,并从那里选择(声明:8和9都不是素数,但它们是相互的素数因为9(mod 8)= 1) 。它没有比那更“完整”,但我仍然不知道这种方法如何分配排列。