【问题标题】:Generating distinct random numbers efficiently有效地生成不同的随机数
【发布时间】:2020-09-09 21:35:05
【问题描述】:

我的主要目的是在图像的像素上随机有效地分布一个缓冲区,但我一直在生成 distinct 随机数。我只是想要生成 0N 之间的数字,但我也希望这些数字是不同的。另请注意,N 通常会很大,例如 2000 万,并且算法不必是加密安全的。

我不能使用随机随机播放方法,因为 N 非常大。我做了一些搜索,发现 Linear congruential generator 但参数 m 必须是素数,但我的 N 有时不是。

最后,我尝试了以下方法,但它不是很有效和可靠,因为它可能会引发超出最大调用堆栈大小错误。

next(max: number)
{
    let num = LCG.next()
    if (num <= max) return num
    return next(max)
}

【问题讨论】:

  • 您的问题实际上没有任何重要的细节。没有关于语言,或者 LCG 的参数,或者为什么你认为你会得到一个堆栈大小错误,或者为什么你在一个简单的循环就足够的情况下使用递归。但是,使用 LCG 解决您所说的问题应该非常有效,只要 LCG 模数小于 2*N。但是,如果您需要加密质量安全,那么 LCG 将不够好。
  • 很抱歉让您感到不适,虽然这不是一个正当的借口,但这是我在网上的第一个问题,我认为语言或参数并不那么重要,但很可能会将它们放在下一个时间。我确实得到了 maximum call stack size error,因为有可能依次获得比 N 大的许多数字,并且我认为循环和递归函数之间没有区别转换为机器代码,但当然它也取决于我没有说明的编程语言是 JavaScript。另外,我不需要加密质量安全。

标签: cryptography steganography


【解决方案1】:

如果数字是不同的,那么它们就不是随机的。随机数可以重复;从不断减少的集合中选择不同的数字。这就是选号有放回和不放放的区别。

您需要从 0 到 2000 万的数字。正如您所发现的,这对于洗牌来说太大了。最好使用加密。因为加密是一对一的,只要你有不同的输入,你就会得到不同的输出。只需加密 0, 1, 2, 3, ... 你就会得到不同的输出。

您谈到使用线性同余 PRNG,所以我认为安全性并不重要。 2000 万大约是 2^24 或 2^26,所以你可以写一个简单的四轮 Feistel cipher 大小合适来完成这项工作。或者,使用带有Format preserving 方法之一的标准库密码将输出保持在您想要的范围内。

【讨论】:

  • 很好的答案;它可能有助于寻找一种算法,这里的通用工具称为“伪随机排列”(PRP),其中分组密码是具有更强属性的子集。
  • 这是一个很棒的答案,也很抱歉没有明确写出它是否加密安全 - 只是更正了它。不过,真的谢谢。
猜你喜欢
  • 2012-01-06
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多