Question
In Java, the following code prints hello world:
System.out.println(randomString(-229985452) + " " + randomString(-147909649));
The randomString() method is:
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();
}
Why does this code generate the exact output hello world? How can seemingly random seeds produce a meaningful phrase?
Short Answer
By the end of this page, you will understand that Java's Random is not truly random. It is pseudorandom, which means the same seed always produces the same sequence of values. This code works because the chosen seeds were carefully selected so that the generated character sequence becomes hello and world. You will also learn how seeding works, how nextInt() drives the output, and why this is predictable rather than magical.
Concept
Java's Random class generates pseudorandom numbers. That means the numbers look random, but they are actually produced by a deterministic algorithm.
The key idea
When you write:
Random ran = new Random(i);
the value i becomes the seed. A seed is the starting point for the random number generator.
If you use the same seed again, Java's Random will generate the same sequence of numbers again.
So this method is not really creating arbitrary strings. It is creating a string based on a predictable number sequence.
What this method does
int k = ran.nextInt(27);
This returns a number from 0 to 26.
0means stop building the string1to26map to letters:1 -> 'a'2 -> 'b'- ...
26 -> 'z'
That mapping happens here:
(char) ('`' + k)
The character '`' comes right before 'a' in ASCII/Unicode. So:
'`' + 1becomes'a''`' + 8becomes'h''`' + 5becomes'e'
Why hello world appears
The seeds -229985452 and -147909649 were chosen so that the number generator produces these sequences:
For -229985452:
8, 5, 12, 12, 15, 0
That maps to:
h, e, l, l, o
For -147909649:
23, 15, 18, 12, 4, 0
That maps to:
w, o, r, l, d
So the result is:
hello world
Why this matters
This is an important programming concept because many systems rely on deterministic pseudorandom generators:
- repeatable tests
- reproducible simulations
- procedural world generation in games
- debugging code that depends on randomness
If you know the seed, you know the output.
Mental Model
Think of Random like a music player with a fixed playlist.
It may sound random, but if you always start from the same track number, you will hear the same songs in the same order.
- The seed is the starting track.
nextInt(27)asks for the next item in the playlist.- Each number becomes a letter.
- When the number
0appears, the song ends.
So the code is not discovering hello world by chance. Someone picked starting points that make the playlist spell those words.
Syntax and Examples
Core syntax
Creating a seeded random generator in Java:
Random random = new Random(123);
int n = random.nextInt(10); // 0 to 9
Generating repeatable output:
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random a = new Random(42);
Random b = new Random(42);
System.out.println(a.nextInt(100));
System.out.println(b.nextInt(100));
}
}
Both lines print the same value because both generators use the same seed.
Beginner-friendly example
import java.util.Random;
public class Main {
public static void main(String[] args) {
System.out.println(makeWord(1));
System.out.println(makeWord(1));
}
public static String makeWord(int seed) {
Random random = new Random(seed);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
int n = random.nextInt(26); // 0 to 25
sb.append((char) ('a' + n));
}
return sb.toString();
}
}
Because the seed is the same each time, both calls to makeWord(1) produce the same 5-letter string.
How the original code maps numbers to letters
(char) ('`' + k)
Examples:
| k | Result |
|---|---|
| 1 | a |
| 2 | b |
| 8 | h |
| 12 | l |
| 15 | o |
| 23 | w |
| 0 | stop |
So a sequence like 8, 5, 12, 12, 15, 0 becomes hello.
Step by Step Execution
Traceable example
Consider this simplified method:
public static String randomString(int seed) {
Random ran = new Random(seed);
StringBuilder sb = new StringBuilder();
while (true) {
int k = ran.nextInt(27);
if (k == 0) {
break;
}
sb.append((char) ('`' + k));
}
return sb.toString();
}
Now imagine the generator returns this sequence for a specific seed:
8, 5, 12, 12, 15, 0
Step by step
-
Create
Random ran = new Random(seed)- The seed fixes the number sequence.
-
Create an empty
StringBuildersb = ""
-
First loop:
k = 8- not
0, so append'`' + 8='h' sb = "h"
-
Second loop:
k = 5- append
'e' sb = "he"
-
Third loop:
k = 12- append
'l' sb = "hel"
-
Fourth loop:
k = 12- append
'l' sb = "hell"
-
Fifth loop:
k = 15- append
'o' sb = "hello"
-
Sixth loop:
k = 0- stop the loop
-
Return
"hello"
The second seed does the same thing, but its sequence maps to world.
Important detail
The loop ends only when nextInt(27) returns 0. Since the generator is deterministic, the position of that 0 is also determined by the seed.
Real World Use Cases
Where seeded randomness is useful
Repeatable tests
Developers use fixed seeds so test results stay consistent:
Random random = new Random(12345);
This helps reproduce bugs.
Games and procedural generation
A game may generate the same map from the same seed.
- same seed -> same world
- different seed -> different world
Simulations
Scientific or financial simulations often need results that can be rerun exactly.
Debugging
If a bug happens with seed 9876, the developer can rerun the exact same sequence.
Demo data generation
You can generate fake but predictable names, IDs, or values for development.
Where this exact string-building idea appears
- creating random-looking usernames
- generating sample words for tests
- encoding hidden messages or puzzles
- challenge problems that demonstrate deterministic randomness
Real Codebase Usage
In real projects, developers usually do not use Random to hide words in code, but they do use the same underlying idea: fixed seeds create repeatable behavior.
Common patterns
Reproducible test setup
Random random = new Random(100);
Used in unit tests to generate the same sample data every run.
Dependency injection of randomness
Instead of creating new Random() inside a method, developers often pass a Random object in.
public String generateCode(Random random) {
// use random here
}
This makes the code easier to test.
Guarding against infinite loops
The original code depends on eventually getting 0. In production code, developers often add limits.
for (int count = 0; count < 100; count++) {
int k = random.nextInt(27);
if (k == 0) break;
}
Validation and configuration
Seeds may come from config files, test settings, or command-line arguments so output is reproducible.
Design lesson from this example
The surprising part is not the phrase itself. The real lesson is:
- pseudorandom generators are deterministic
- seeds fully control the sequence
- meaningful output can be engineered by choosing the right seed
Common Mistakes
1. Thinking Random is truly random
Beginners often assume this:
Random r = new Random(5);
means the result will be unpredictable. It will not. The same seed always gives the same sequence.
Avoid it
Use a fixed seed only when you want repeatable output.
2. Creating a new Random every time without understanding the effect
Broken idea:
public int getNumber() {
Random r = new Random(123);
return r.nextInt(10);
}
This returns the same first value every call.
Better
Random r = new Random(123);
public int getNumber() {
return r.nextInt(10);
}
3. Misunderstanding nextInt(bound)
Some beginners think this returns 1 to bound.
random.nextInt(27);
Actually returns:
0 to 26
That is why 0 can be used as the stop signal.
4. Forgetting character arithmetic rules
Broken expectation:
(char)('a' + 1) // many expect 'a'
But that is actually 'b'.
In the original code, using '`' instead of 'a' shifts the mapping so 1 becomes 'a'.
5. Assuming meaningful output happened by luck
The phrase did not appear by accident. The seeds were chosen intentionally.
6. Risking very long loops
This code stops only when k == 0.
while (true) {
int k = ran.nextInt(27);
if (k == 0) break;
}
It will eventually stop for normal use, but in real code it is safer to set a maximum length.
Comparisons
Seeded vs unseeded randomness
| Approach | Behavior | Repeatable? | Common use |
|---|---|---|---|
new Random(123) | Same sequence every run | Yes | Testing, debugging, reproducible generation |
new Random() | Seed based on current state/time | Usually no | General-purpose randomness |
Pseudorandom vs true random
| Type | Meaning | Predictable from seed? | Typical source |
|---|---|---|---|
| Pseudorandom | Generated by algorithm | Yes | Random, software PRNGs |
| True random | Based on physical randomness | No | Hardware events, physical noise |
Random vs SecureRandom
| Class | Best for | Predictable with same seed? | Use for passwords? |
|---|---|---|---|
Random | Games, tests, simulations | Yes | No |
SecureRandom | Security-sensitive values | Designed to resist prediction | Yes |
StringBuilder vs string concatenation in a loop
| Approach | Good for loops? | Why |
|---|---|---|
StringBuilder | Yes | Efficient for repeated appends |
String with + | Usually no | Creates many intermediate strings |
Cheat Sheet
Quick reference
Seeded random
Random r = new Random(123);
- Same seed -> same sequence
- Different seed -> different sequence
nextInt(bound)
r.nextInt(27);
Returns an int from:
0 to 26
Character mapping in the original code
(char) ('`' + k)
1 -> a2 -> b...26 -> z0 -> stop
Original logic
while (true) {
int k = ran.nextInt(27);
if (k == 0) break;
sb.append((char) ('`' + k));
}
Why hello world appears
- The seeds were chosen intentionally.
- They produce number sequences that map to letters.
- The first seed maps to
hello. - The second seed maps to
world.
Important rules
Randomis pseudorandom, not truly random.- Recreating
Randomwith the same seed resets the sequence. - Fixed seeds are useful for testing and reproducibility.
- Do not use
Randomfor security-sensitive values.
Safer loop pattern
for (int i = 0; i < 100; i++) {
int k = ran.nextInt(27);
if (k == 0) break;
sb.append((char) ('`' + k));
}
FAQ
Why does the same seed always give the same output in Java?
Because Random uses a deterministic algorithm. The seed defines the starting state, and the same starting state produces the same sequence.
Is Java Random actually random?
No. It is pseudorandom. The values appear random, but they are generated by a predictable process.
Why does nextInt(27) allow the loop to stop?
Because it can return 0 through 26. The code uses 0 as a signal to break out of the loop.
Why is '`' used instead of 'a'?
Because '`' is the character before 'a'. That makes 1 map to 'a', 2 to 'b', and so on.
Were those seed values discovered by chance?
Most likely not. They were almost certainly chosen specifically so the generated sequences spell hello and world.
Can I use this trick to generate other words?
Yes. If you can find seeds that produce the needed sequence, you can generate specific words.
Should I use Random for passwords or tokens?
No. Use SecureRandom for security-sensitive data.
Why is StringBuilder used here?
Because strings are being built character by character in a loop, and StringBuilder is more efficient than repeated string concatenation.
Mini Project
Description
Build a small Java program that demonstrates how seeded randomness creates repeatable words. The program should generate a word from a seed, print the same word for the same seed, and show different output for a different seed. This helps reinforce that Random is deterministic, not magical.
Goal
Create a Java program that turns seeded pseudorandom numbers into lowercase words and proves that the same seed always produces the same result.
Requirements
[ "Write a method that accepts an integer seed and returns a generated word.", "Use Random with the provided seed.", "Convert numbers into lowercase letters.", "Stop after a fixed number of letters or when a stop condition is reached.", "Show that the same seed produces the same word twice." ]
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.