Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 基2范围内整数的最小完美散列_C_Hash_Integer_Range_Perfect - Fatal编程技术网

C 基2范围内整数的最小完美散列

C 基2范围内整数的最小完美散列,c,hash,integer,range,perfect,C,Hash,Integer,Range,Perfect,我想要的是一个简单的散列函数,它将取一个在基2范围内的整数,然后(随机)散列到该范围内的另一个整数,而不会发生冲突。这将用于构造置换,最好是从种子值。所以仅仅抵消整数和调制是不起作用的。有谁知道用C写的好选项吗 谢谢, Josh这可能会有所帮助(参见底部了解更一般的方法):允许您选择k“种子”值、n“最大”值,并以非常有效的方式将自然数从零排列到n-1(k可以在Z中,但最好是两个自然数)。如果你想要一个排列,唯一的问题是n必须是一个素数,我不确定所有的排列是否均匀分布在种子空间中(关于这方面的一

我想要的是一个简单的散列函数,它将取一个在基2范围内的整数,然后(随机)散列到该范围内的另一个整数,而不会发生冲突。这将用于构造置换,最好是从种子值。所以仅仅抵消整数和调制是不起作用的。有谁知道用C写的好选项吗

谢谢, Josh

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

然后,在伪代码中,主操作将如下所示:

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;
}
这并不完全是你想要的,但经过一些调整,它可以正常工作。。。除非我们谈论的是高端安全产品。也许最简单的解决方案是选择接近二次幂的素数,并进行一些调整?

如果有帮助,请告诉我

编辑我无法在我的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)
(定义排列(n种子)
“打印介于0和n-1之间的一组数字的排列,
假设n是素数“
(让((排列的(n以下i的循环收集(%(*i种子)n)))
(打印排列)

我在安德鲁·肯斯勒(Andrew Kensler)的论文中找到了一个很好的解决方案。这里,一个置换是使用一个仅由可逆算子组成的混合函数构造的。这保证了在二次幂范围内不会发生碰撞

该函数是通过使用爬山程序迭代发现的,该程序根据每个候选函数的avalaunch属性对其进行评估。此外,Kensler通过使用一种称为循环行走的技术对哈希进行了推广,以允许范围不是二的幂


鉴于这一点,结果的质量以及容易对排列置乱的能力,建议的函数是对原始问题的一个很好的解决方案。有关可逆运算符和生成高质量混合函数的更多详细信息,请参阅Bret Mulvey关于hash函数的文章。

Hi!我想起了一些涉及对称群的内容.我明天可以检查,但如果你想同时检查,也许你会在这里发现一些东西:谢谢@fr_andres,我会仔细检查一下。例如,如果你不想0映射到0,你可以在所有结果中添加任意随机整数,然后再次计算模n…感谢@fr_andres,这看起来像尽管有限制,但这是一个很好的解决方案。我将它用作(t,s)-序列中区间的排列,2^7是一个合理的大小。酷!:)正如我所说,有一些肮脏的解决方法,所以请让我知道它是否足够……如果你能分享你的解决方案,那将是非常好的。干杯!我会分享任何出现的其他解决方案,会留意更普遍的东西。谢谢我相信如果你的
k
(种子)是素数,你的
n
可以是一个素数。但这样排列空间就会明显更小…很好!我会检查它
(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)