加密洗牌

2021-05-08 22:55:42

如果我需要洗牌一个列表,而且可以在记忆中举行整个东西吗?或者如果我没有想要洗牌,但只是以洗牌的方式遍历它? (即,以随机的方式访问每个元素一次,只有一次。)如果我想遍历它,但没有想以某种原因预先编译或存储遍历遍布或存储遍历的情况

这将允许我以从外部不可预测的顺序发布列表中的项目,但实际上是确定性和基于秘密密钥,而不预先计算任何东西(或担心碰撞)。或者我可以使用它来指定小的非顺序ID,最终将以伪andom顺序饱和n个字符串的空间,遮挡了任何可以查看分配的ID的某些子集的人的真实大小。他们甚至能够讲述他们可以观察到的ID列表中存在差距。

基本上,我' d想要的是列表索引的伪随机置换。如果列表有1000个元素,我的' d需要的是[0,1,2,...,998,999]的混组清单,而是一种以同样的方式生产该列表的方法每次。我在15年前第一次遇到这个问题,从那时起,从那时起,在不同的时间里愚蠢地思考它,但是没有真正有工具来回答它。然后几个月前我在Freenode IRC和Alipha上询问了## Crypto提出了一个很好的解决方案:加密索引。

具体而言,他们建议的是在CTR模式下使用FEISTEL密码。我没有真正了解数学,但重要的是Feistel密码会产生一个键控的伪随机排列。也就是说,给定加密密钥,如果您使用它来加密(例如)每种可能的16字节输入,则输出也是每个可能的16字节值的列表 - 但是以不同的顺序,以及您可以&# 39; T预测而不知道加密密钥。不同的钥匙,不同的顺序。 (此属性还有其他密码,但Feistel Ciphers允许您加密数据大小的任何数量,而不仅仅是在N字节块中。这变得很重要。)

CTR模式通常是指通过从计数器中产生键盘来加密数据流的方式,但这里' s在隐喻上使用了一点。列表的索引基本上是从0到n-1递增的计数器。为了简单起见,'我们' ll假设n是2的力量(例如2 ^ k)。然后,每个索引可以用二进制表示为消息k比特。使用Feistel密码加密索引值的二进制表示,并将结果二进制返回为数字,我们将新索引列入列表中。如果以这种方式加密每个索引,结果是索引的播放列表。在这里'它可能看起来像n = 16:

索引:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]加密:[9,4,8​​,1,7,11, 13,10,6,14,0,3,5,15,2,12]

然后,这些可以用作原始列表中的索引:索引9,索引4,索引8等。当然,你不必抓住这个加密索引列表。只要您拥有用于加密它们的密钥,就可以在飞行中生成它们。 (它们也可以使用相同的密钥解密。)但是关键洞察力是您可以直接以随机订单遍历列表。例如,如果您目前在列表中的索引8并希望了解下一个"随机"位置,您将首先解密8查找2(从底部列表中的8到顶部列表中的匹配位置,a 2),递增2到3,然后加密(再次下降)从3到1.如此遍历中的下一步是8到1.解密,增量,加密。 (如果递增将使您删除列表的末尾,只需缠绕“。)

Warning: Can only detect less than 5000 characters

2021-05-06#2:我发现了一篇论文"北美野牛:实例化了白色的交换或非建筑" 这似乎是第一个交换的具体实例 - 或者,显然它是不可避免的缓慢!