【问题标题】:Numeric, reversible, pseudorandom number generator, for very large numbers数字、可逆、伪随机数生成器,用于非常大的数字
【发布时间】:2013-03-03 01:30:06
【问题描述】:

有人知道符合上述所有标准的算法吗?我需要指定一个种子编号,以及我希望输出编号所属的范围(这也是输入编号所在的范围)。这个函数还需要有一个反向操作的对应项。

例如:

我传递种子 5 和范围 5-35,然后我收到数字 27。然后我可以将它传递给一个反转操作的函数,使用相同的范围,这将返回数字 5。

我不能存储原始数字,也不能遍历输入数字的列表。这不一定是加密强度,它必须尽可能快。

我能想到的唯一符合这种描述的就是加密算法。即使是正确方向的一点也很棒。

编辑

我正在尝试找到一种方法来表示一组太大而无法在内存中保存的随机(看起来)数字(可能是 3e12 个数字),然后测试该集合中是否出现某些范围的数字。

例如。如果我有一个函数可以给我随机集合(4、22、7、343、67、38、2),我想说,给我该集合中介于 1 和 30 之间的数字,并且取回集合 (4, 22, 7, 2)。

【问题讨论】:

  • 请您编辑问题以准确解释您要达到的目标吗?我已经发布了一个答案来解释为什么你所要求的是不可能的。
  • 我已经编辑了这个问题。另外,我已经想到了一种方法来完成我之前提出的依赖于随机数生成器的问题。问题是它实际上并没有帮助。
  • 没关系,我的方法行不通,它依赖于每个随机数的相同种子,它不会给出一组随机数......这比我想象的更难破解。

标签: encryption random


【解决方案1】:

正如 RB 所说,您需要加密,而不是 RNG。使用给定的密钥,加密是可逆的。如果您希望同一种子具有不同的结果但范围已更改,则密钥也可以包含种子和范围。

范围大小是一个不同的问题。对于 32 位范围,使用 DES。对于 64 位使用 AES。对于其他范围,请编写您自己的简单Feistel cypher 或使用为所有尺寸定义的Hasty Pudding cypher

无论您使用何种底层密码,您始终可以使用 Hasty Pudding 方法在适当的范围内找到一个数字:只需继续加密输出,直到它在所需的范围内。一旦你有合适大小的东西,你可以添加下限来获得你需要的数字。因此,对于 5 到 35 的范围,您将在 [0..30] 中生成一个数字并添加 5。

ETA:在考虑了您的问题之后,您不能将种子用作密钥的一部分。如果你这样做,你将无法重建密钥来解密你的随机数。您只能在开始逆向过程时知道的密钥中使用数据。

您还需要一种识别种子的方法。当你解密时,你会得到一系列数字;您需要一种方法来找出哪个是原始种子。也许您可以将种子限制在指定的范围内(或其从零开始的等价物),并在解密系列中选择第一个处于正确范围内的种子。

【讨论】:

  • 啊,这就是我要找的东西,这些看起来可以解决我的问题。谢谢。
  • @Patrick:顺便说一下,您要查找的内容的总称是format-preserving encryption
【解决方案2】:

不,这是不可能的。随机数生成器可以从多个不同的种子生成相同的输出(在这方面它就像一个散列算法从不同的输入生成相同的输出)。

例如,PRNG 可能像这样工作(伪代码):

PRNG randomWithSeed5 = new PRNG(seed: 5);
PRNG randomWithSeed6 = new PRNG(seed: 6);
PRNG randomWithSeed7 = new PRNG(seed: 7);

randomWithSeed5.NextInt(range: 5-50); //returns 20
randomWithSeed6.NextInt(range: 5-50); //returns 20
randomWithSeed7.NextInt(range: 5-50); //returns 32

在这一点上,很明显不可能编写一个解码算法,给定输入 20,可以返回正确的种子 - 您无法确定 56 是否是正确的答案。

听起来加密算法会更好地满足您的需求 - 我什至不明白为什么涉及随机数生成器。

【讨论】:

    猜你喜欢
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2017-09-07
    • 2016-10-23
    • 1970-01-01
    • 2012-02-09
    相关资源
    最近更新 更多