我正在寻找一个有效的,均匀分布的PRNG,它为平原中的任何整数点生成一个随机整数,坐标x和y作为函数的输入。
int rand(int x, int y)
每次输入相同的坐标时,它必须提供相同的随机数。
您是否知道可用于此类问题的算法以及更高维度的算法?
我已经尝试使用像LFSR这样的普通PRNG,并将x,y坐标合并在一起,将其用作种子值。这样的事情。
int seed = x << 16 | (y & 0xFFFF)
此方法的明显问题是种子不会多次迭代,但会针对每个x,y点再次初始化。如果您想象结果,这会导致非常丑陋的非随机模式。
我已经知道使用某种大小的混乱排列表的方法,如256,你可以得到一个像这样的随机整数。
int r = P[x + P[y & 255] & 255];
但我不想使用这种方法,因为范围非常有限,受限制的时间长度和高内存消耗。
感谢任何有用的建议!
答案 0 :(得分:3)
我发现了一个基于xxhash算法的非常简单,快速且充足的哈希函数。
gradle extractTpcds
现在它比我上面描述的查找表方法快得多,它看起来同样随机。我不知道随机属性是否与xxhash相比是好的,但只要看起来随机,它就是我公平的解决方案。
这是像素坐标作为输入的样子:
答案 1 :(得分:2)
一般来说,我认为你想要一些哈希函数(大多数都是为了输出随机性而设计的; RNG的雪崩效应,明确需要CryptoPRNG的随机性)。与this线程比较。
以下代码使用此方法:
最后一步是通过this方法完成的,这似乎不是那么快,但具有很强的理论保证(使用了选定的答案)。
我使用的哈希函数支持种子,将在步骤3中使用!
import xxhash
import math
import numpy as np
import matplotlib.pyplot as plt
import time
def rng(a, b, maxExclN=100):
# preprocessing
bytes_needed = int(math.ceil(maxExclN / 256.0))
smallest_power_larger = 2
while smallest_power_larger < maxExclN:
smallest_power_larger *= 2
counter = 0
while True:
random_hash = xxhash.xxh32(str((a, b)).encode('utf-8'), seed=counter).digest()
random_integer = int.from_bytes(random_hash[:bytes_needed], byteorder='little')
if random_integer < 0:
counter += 1
continue # inefficient but safe; could be improved
random_integer = random_integer % smallest_power_larger
if random_integer < maxExclN:
return random_integer
else:
counter += 1
test_a = rng(3, 6)
test_b = rng(3, 9)
test_c = rng(3, 6)
print(test_a, test_b, test_c) # OUTPUT: 90 22 90
random_as = np.random.randint(100, size=1000000)
random_bs = np.random.randint(100, size=1000000)
start = time.time()
rands = [rng(*x) for x in zip(random_as, random_bs)]
end = time.time()
plt.hist(rands, bins=100)
plt.show()
print('needed secs: ', end-start)
# OUTPUT: needed secs: 15.056888341903687 -> 0,015056 per sample
# -> possibly heavy-dependence on range of output
答案 2 :(得分:1)
您可以使用各种randomness extractors来实现目标。至少有两个来源可以寻找解决方案。
总而言之,您最好使用:
因此,您可以连接坐标,获取其字节,添加随机密钥(对于AES和HMAC)或SHA的盐,并且您的输出具有足够的熵。 根据NIST,输出熵依赖于输入熵:
假设你使用SHA1;因此 n = 160bits 。我们假设 m = input_entropy (你的坐标&#39;熵)
请参阅NIST sp800-90c(第11页)