Wer statt dem doch relativ langweiligen Hello-World-Programm
System.out.println("hello world");
einmal außergewöhnlichen Java-Code nutzen will, um in Java „hello world“ auf der Konsole auszugeben, der wird sich wahrscheinlich über folgendes Hello-World-Beispiel in Java freuen:
System.out.println(randomString(-229985452) + " "
+ randomString(-147909649));
Die randomString
-Methode sieht dabei folgendermaßen aus:
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((char)('`' + k));
}
return sb.toString();
}
Das angegebene Beispiel gibt, wie der Standard-Code für Hello World in Java, genauso „hello world“ auf der Konsole aus.
Diese Ausgabe von „hello world“ wird umständlicher, jedoch auf sehr verblüffende Weise erreicht – nämlich mit Zufallszahlen (durch ein Random-Objekt -> java.util.Random).
Doch wie funktioniert es, dass trotz der Nutzung von Zufallszahlen jedes Mal „hello world“ erzeugt wird?
Warum wird so „Hello World“ ausgegeben?
Mit den zwei Methodenaufrufen randomString(-229985452)
und randomString(-147909649)
wird jeweils als Parameter ein Integer-Wert i
zur Initialisierung der Random-Objekte übergeben. Was bewirkt eine Initialisierung von Random
mit einem Integer?
Zufallszahlen sind nicht zufällig
Zur Ausgabe von „hello world“ wird die Tatsache ausgenutzt, dass Zufallszahlen in Computern nie wirklich zufällig, sondern nur pseudozufällig sind. Pseudozufällig heißt, dass diese Zufallszahlen nicht wirklich zufällig entstehen, sondern von einem Algorithmus generiert (also berechnet) werden müssen. Dieser Algorithmus wird normalerweise (ohne Übergabe eines Integers bei new Random()
) mit einem möglichst zufälligen Wert, dem Seed, initialisiert. Mit diesem Seed berechnet der Zufallszahlen-Generator dann jede Zahl. Bei einer Initialisierung mit dem gleichen Seed werden so also auch gleiche „Zufallszahlen“ erzeugt. In der Praxis wird der Seed aus einer Kombination der Uhrzeit und einem Counter berechnet, so dass er relativ zufällig, schwer zu erraten und die Generierung von zwei gleichen Seeds sehr unwahrscheinlich ist.
In diesem Fall wird der Seed aber manuell übergeben und nicht möglichst zufällig berechnet. Es wird die Eigenschaft genutzt, dass durch die Initalisierung von Random mit einer festen Zahl, in diesem Fall -229985452, immer die selben Zahlen generiert werden. Bei einem Aufruf sind die Zahlen dann immer gleich:
Random r = new Random(-229985452);
int acht = r.nextInt(27);
int fuenf = r.nextInt(27);
int zwoelf = r.nextInt(27);
// usw.
So kann man also nacheinander und zwar jedes Mal und auf jedem Rechner folgende Zahlen generieren:
8
5
12
12
15
0
Und bei der Initialisierung mit -147909649 immer folgende Zahlen generieren:
23
15
18
12
4
0
Doch wie ist es möglich, dass „hello world“ aus diesen Zahlen wird?
Wie wird aus Zufallszahlen „hello world“?
Innerhalb der Schleife werden also bei beiden Aufrufen immer die oben genannten Zahlen generiert. Die Zahlen werden dann zu dem Zeichen „`“ (Nr. 96) addiert. Das Ergebnis dieser Addition ist ein Integer, der für ein Zeichen im Alphabet steht. Mit einem Casting zu char wird aus dem Integer dann schlussendlich ein Zeichen, welches an den String angehängt werden kann. So entsteht char für char erst beim ersten Aufruf der String „hello“ und beim zweiten Aufruf dann „world“:
Generierung von „hello world“
Generierte Zahl
|
Offset
|
Ergebnis der Addition: ‚`‘ + k
|
Buchstabe (char)
|
8
|
96
|
104
|
h
|
5
|
96
|
101
|
e
|
12
|
96
|
108
|
l
|
12
|
96
|
108
|
l
|
15
|
96
|
111
|
o
|
|
|
break -> return „hello“
|
|
23
|
96
|
119
|
w
|
15
|
96
|
111
|
o
|
18
|
96
|
114
|
r
|
12
|
96
|
108
|
l
|
4
|
96
|
100
|
d
|
|
|
break -> return „world“
|
|
Die erzeugten Strings werden dann verkettet und am Schluss als „hello world“ auf der Konsole ausgegeben.
Vielleicht gelingt es einigen von euch mit diesem Hello-World-Programm in Java andere zu verblüffen…
Quelle: Stack Overflow
Lizenz: CC BY-SA 3.0. Ich würde mich über eine Verlinkung freuen!