|
198
|
| Sergey Emeliyanov · 技术社区 · 8 年前 |
|
|
1
152
选择一个随机排列需要同时比你的问题所暗示的更多和更少的随机性。让我解释一下。 坏消息是:需要更多的随机性。 您的方法的根本缺陷是它试图在~2之间进行选择 226个 使用64位熵的可能性(随机种子)。在~2之间进行公平选择 226个 可能你必须找到一种方法来产生226位的熵,而不是64位。 有几种方法可以生成随机位: dedicated hardware , CPU instructions , OS interfaces , online services . 在你的问题中已经有一个隐含的假设,你可以以某种方式产生64位,所以只要做你打算做的任何事,只做4次,然后把多余的部分捐给慈善机构。:) 好消息是:减少随机性。
一旦你有了226个随机位,剩下的就可以确定地完成,所以
的性质
假设我们生成所有52个!排列(忍受我)并排序字典。
要选择一个排列,我们只需要一个随机整数
现在,实际上不需要生成所有这些排列。考虑到它在我们假设的排序列表中随机选择的位置,您可以直接生成一个。这可以在O(n)中完成 2个 )使用时间 Lehmer [1] code (另见 numbering permutations 和 factoriadic number system ). 这里的n是你甲板的尺寸,即52。
这里有一个C实现
StackOverflow answer
. 有几个整数变量会溢出n=52,但幸运的是在Java中可以使用
[一] 不可混淆 Lehrer . :) |
|
|
2
60
您的分析是正确的:在伪随机数生成器中植入任何特定的种子在洗牌后必须产生相同的序列,从而将可以获得的排列数限制为2
64个
. 这个断言是
easy to verify experimentally
通过打电话
解决这个问题的方法是使用一个随机数生成器,它允许一个更大的种子。Java提供
|
|
|
3
26
一般来说,如果伪随机数发生器(PRNG)的状态长度小于226位,则它不能从52项列表的所有置换中进行选择。
另请参见我的 article on random number generators . 这种考虑独立于PRNG的性质;它同样适用于密码和非密码PRNG(当然,当涉及信息安全时,非密码PRNG是不合适的)。
尽管
|
|
4
18
让我提前道歉,因为这有点难理解。。。
首先,你已经知道了
然而,事实是 无足轻重 只要你不会生成超过2^64个序列,只要2^64个序列没有“特别的”或“明显的特别的” 可以 生成。 假设你有一个更好的使用1000位种子的PRNG。假设您有两种方法来初始化它——一种方法是使用整个seed初始化它,另一种方法是在初始化seed之前将其散列到64位。 如果你不知道哪个初始化器是哪个,你能写一些测试来区分它们吗?除非你足够幸运地用 相同的 64位两次,那么答案是否定的。如果不详细了解特定PRNG实现中的某些弱点,就无法区分这两个初始值设定项。
或者,想象一下
所以事实上
当然,为了 密码学 目的是,64位种子是不够的,因为让系统使用同一种子两次在计算上是可行的。 编辑:
我要补充的是,尽管上面的所有内容都是正确的,但是
|
|
|
5
10
我要在这件事上另辟蹊径。你的假设是对的-你的PRNG不可能全部达到52!可能性。 问题是:你的纸牌游戏规模有多大? 如果你在做一个简单的克朗代克风格的游戏? 那你肯定不会 需要 全部52人!可能性。相反,请这样看:一个玩家将有18个 五百万 独特的游戏。即使考虑到“生日问题”,他们也要玩数十亿次的手才能碰到第一个重复的游戏。 如果你在做蒙特卡罗模拟? 那你就是 可能 可以。你可能需要处理由于PRNG中的“P”而产生的工件,但是你可能不会仅仅因为种子空间太小而遇到问题(同样,你正在寻找千千万万种独特的可能性)。另一方面,如果你正在处理大量的迭代,那么,是的,你的种子空间太小可能是一个交易破坏者。 如果你正在做一个多人纸牌游戏,特别是如果有钱在网上? 然后你需要做一些关于在线扑克网站如何处理你询问的问题的谷歌搜索。因为低种子空间问题不是 值得注意的 对于普通玩家来说 可利用的 如果值得花时间的话。(扑克网站都经历了一个阶段,他们的prng被‘黑客’入侵,让人看到所有其他玩家的洞牌,只需从暴露的牌中推断出种子即可。)如果这就是你所处的情况, 不要 只需找到一个更好的PRNG-你将需要像对待密码问题一样认真对待它。 |
|
6
9
与dasblinkenlight基本相同的短解决方案:
你不需要担心内部状态。详细解释原因:
当您创建
此输入(!)可能还含有虚假的痕迹
加密强哈希,用于删除这些跟踪。这就是使用这些csprng的原因,而不是创建这些数字本身!这个
简而言之:简单地忘记反对和使用
|
|
|
7
4
如果您认为这个数字只是一个位(或字节)数组,那么您可以使用(Secure)
|
|
|
8
3
一个非常简单的算法是将SHA-256应用于从0向上递增的整数序列。(如果希望“获得不同的序列”,可以附加一个salt)如果我们假设SHA-256的输出“与”0到2之间的均匀分布整数“一样好” 256个 -1那么我们有足够的熵来完成这个任务。 要从SHA256的输出中得到一个置换(当它被表示为整数时),只需要将它减少到52,51,50的模。。。在这个伪代码中:
|
|
Vessel · Ruby-包含任意数量元素的所有排列 2 年前 |
|
|
alexey · 为什么Networkx中的图形将箭头指向错误的方向? 2 年前 |
|
|
K123 · 对于一个特定的N位数字,有多少不同的数字排列? 2 年前 |
|
|
psychcoder · 从多个列表生成子集N的组合 3 年前 |
|
|
Ross · 使用=MAKEARRAY制作组合的Excel公式 3 年前 |
|
|
yonetpkbji · Perl在url中每次出现斜线后从文件中插入字符串 13 年前 |