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