以下print语句将打印“hello world” . 谁能解释一下呢?
System.out.println(randomString(-229985452) + " " + randomString(-147909649));
并且 randomString()
看起来像这样:
public static String randomString(int i)
{
Random ran = new Random(i);
StringBuilder sb = new StringBuilder();
while (true)
{
int k = ran.nextInt(27);
if (k == 0)
break;
sb.append((char)('`' + k));
}
return sb.toString();
}
14 回答
以下是Denis Tulskiy answer的一个小改进 . 它将时间缩短了一半
我写了一个快速程序来找到这些种子:
我现在在后台运行它,但它已经找到了足够的经典pangram字:
(Demo on ideone.)
PS .
-727295876, -128911, -1611659, -235516779
.主体是使用相同种子构造的随机类,每次都会生成相同的数字模式 .
当使用特定种子参数(在本例中为
-229985452
或-147909649
)构造java.util.Random
的实例时,它遵循以该种子值开头的随机数生成算法 .每个使用相同种子构造的
Random
每次都会生成相同的数字模式 .这里的每个人都很好地解释了代码是如何工作的,并展示了如何构建自己的示例,但这里有一个信息理论答案,说明为什么我们可以合理地期望蛮力搜索最终会找到解决方案 .
26个不同的小写字母组成了我们的字母
Σ
. 为了允许生成不同长度的单词,我们进一步添加终止符号⊥
以产生扩展字母Σ' := Σ ∪ {⊥}
.设_194143_为符号,X为均匀分布的随机变量,超过
Σ'
. 获得该符号P(X = α)
及其信息内容I(α)
的概率由下式给出:对于一个单词
ω ∈ Σ*
及其⊥-
终止对应ω' := ω · ⊥ ∈ (Σ')*
,我们有由于伪随机数发生器(PRNG)是用32位种子初始化的,我们可以期待大多数单词的长度达到
由至少一个种子生成 . 即使我们要搜索一个6个字符的单词,我们仍然会在41.06%的时间内获得成功 . 不是太寒酸 .
对于7个字母,我们看起来接近1.52%,但在尝试之前我没有意识到:
看输出:http://ideone.com/JRGb3l
根据Denis Tulskiy的答案,此方法生成种子 .
我会把它留在这里 . 谁有很多(CPU)的时间,随时可以试验:)另外,如果你已经掌握了一些fork-join-fu来使这个东西烧掉所有CPU内核(只是线程很无聊,对吧?),请分享你的代码 . 我将不胜感激 .
输出:
我对此很感兴趣,我在字典单词列表上运行了这个随机单词生成器 . 范围:Integer.MIN_VALUE到Integer.MAX_VALUE
我得到了15131次点击 .
打印
随机总是返回相同的序列 . 它用于改组数组和其他操作作为排列 .
要获得不同的序列,必须在某个位置初始化序列,称为“种子” .
randomSting获得"random"序列的i位置(seed = -229985452)中的随机数 . 然后在种子位置之后的序列中使用ASCII代码作为接下来的27个字符,直到此值等于0.这将返回"hello" . 对"world"执行相同的操作 .
我认为代码不适用于任何其他单词 . 编程的人非常了解随机序列 .
这是非常棒的极客代码!
其他答案解释了原因,但这里是如何 .
给定
Random
的实例:r.nextInt(27)
生成的前6个数字是:给出
Random r = new Random(-147909649)
的r.nextInt(27)
生成的前6个数字是:然后只需将这些数字添加到字符 ``` (即96)的整数表示中:
事实上,大多数随机数发生器都是"pseudo random."它们是线性同余发生器或LCG(http://en.wikipedia.org/wiki/Linear_congruential_generator)
鉴于固定种子,LCG是可预测的 . 基本上,使用为您提供第一个字母的种子,然后编写一个继续生成下一个int(char)的应用程序,直到您点击目标字符串中的下一个字母并记下您必须调用LCG的次数 . 继续,直到你生成每一个字母 .
这是关于“种子” . 相同的种子给出相同的结果 .
由于使用Java可以轻松实现多线程,因此以下是使用所有可用内核搜索种子的变体:http://ideone.com/ROhmTA
从Java文档中,这是为Random类指定种子值时的一个有意的功能 .
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html
但奇怪的是,您会认为存在可预测的“随机”数字存在隐含的安全问题 .