ランダム関数による hello world
stackoverflowの3日の記事でJavaによる「hello workd」なプログラムについて書かれてました。
Why does this code print “hello world”?
[java]
System.out.println(
randomString(-229985452) + " " + randomString(-147909649));
public static String randomString(int i){
Random ran = new Random(i);
StringBuilder sb = new StringBuilder();
for (int n = 0; ; n++){
int k = ran.nextInt(27);
if (k == 0)
break;
sb.append*1;
}
return sb.toString();
}
[/java]
ちょっと???なコードですが、実行してみると確かにhello worldが表示されてます。
記事を読んでみると、すぐに分かりますが、初期化に使用するSeed値で疑似乱数が規則的に現れることを利用して、hello\0とworld\0のパターンになるSeed値を指定しているだけでした。
8 + 96 = 104 --> h 5 + 96 = 101 --> e 12 + 96 = 108 --> l 12 + 96 = 108 --> l 15 + 96 = 111 --> o 23 + 96 = 119 --> w 15 + 96 = 111 --> o 18 + 96 = 114 --> r 12 + 96 = 108 --> l 4 + 96 = 100 --> d
Javaと.NETでは、当然Randomの実装が違いますので、同じコードを実行してみても当然ながら「hello world」にはなりません。
ってことで、.NETのRandomでも同じパターンが無いか検索してみました。
class Program { private static void Main(){ for (var i = Int32.MinValue; i < Int32.MaxValue; i++){ SearchHello(i); SearchWorld(i); } } static void SearchHello(int i){ //8,5,12,12,15,0を検索する Random ran = new Random(i); int n = ran.Next(27); if (n - 3 != ran.Next(27)) return; if (n + 4 != ran.Next(27)) return; if (n + 4 != ran.Next(27)) return; if (n + 7 != ran.Next(27)) return; if (n - 8 == ran.Next(27)){ Console.WriteLine(string.Format( "find [Hello] {0} {1} {2} {3} {4} {5}" , n , n-3,n+4,n+4,n-3,i)); } } static void SearchWorld(int i) { //23,15,18,12,4,0を検索する var ran = new Random(i); var n = ran.Next(27); if (n - 8 != ran.Next(27)) return; if (n - 5 != ran.Next(27)) return; if (n - 11 != ran.Next(27)) return; if (n - 19 != ran.Next(27)) return; if (n - 23 == ran.Next(27)) { Console.WriteLine(String.Format( "find [World] {0} {1} {2} {3} {4} {5}" , n, n - 3, n + 4, n + 4, n - 3, i)); } } }
結果は、下記のような感じ・・・・
find [World] 26 23 30 30 23 -2055333802 find [World] 24 21 28 28 21 -1992937727 // <=これと find [Hello] 18 15 22 22 15 -1986525298 find [Hello] 15 12 19 19 12 -1979516206 find [Hello] 16 13 20 20 13 -1976927369 find [Hello] 8 5 12 12 5 -1956515490 find [Hello] 13 10 17 17 10 -1947267267 find [Hello] 19 16 23 23 16 -1935430207 find [Hello] 14 11 18 18 11 -1896172176 find [Hello] 9 6 13 13 6 -1777252898 // <=これを使う find [Hello] 15 12 19 19 12 -1765415838 find [World] 24 21 28 28 21 -1730331105 find [Hello] 10 7 14 14 7 -1726157807 find [Hello] 16 13 20 20 13 -1714320747 find [World] 24 21 28 28 21 -1681824851
一応パターンが見つかったので、C#版です。
*1:char)('`' + k