Java中使用随机字符串代码打印'hello world'的原因解析

Java中使用随机字符串代码打印’hello world’的原因解析

技术背景

在Java编程中,java.util.Random 类常用于生成随机数。但实际上,它生成的是伪随机数,即通过特定的算法和初始种子值来确定后续的随机数序列。当使用相同的种子值创建 Random 实例时,会生成相同的随机数序列。

实现步骤

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Main {
public static void main(String[] args) {
System.out.println(randomString(-229985452) + " " + randomString(-147909649));
}

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();
}
}

步骤解释

  1. 创建 Random 实例:在 randomString 方法中,使用传入的整数 i 作为种子值创建 Random 实例。
  2. 生成随机数:通过 ran.nextInt(27) 生成 0 到 26 之间的随机整数。
  3. 字符转换:将生成的随机整数 k 加上字符 (其 ASCII 码为 96),转换为对应的字符,并添加到StringBuilder` 中。
  4. 终止条件:当生成的随机整数 k 为 0 时,停止循环。
  5. 返回结果:将 StringBuilder 中的内容转换为字符串并返回。

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Random r1 = new Random(-229985452);
Random r2 = new Random(-147909649);

// 生成 "hello"
int[] helloNums = new int[6];
for (int i = 0; i < 6; i++) {
helloNums[i] = r1.nextInt(27);
}

// 生成 "world"
int[] worldNums = new int[6];
for (int i = 0; i < 6; i++) {
worldNums[i] = r2.nextInt(27);
}

// 字符转换
StringBuilder hello = new StringBuilder();
for (int num : helloNums) {
if (num != 0) {
hello.append((char) ('`' + num));
}
}

StringBuilder world = new StringBuilder();
for (int num : worldNums) {
if (num != 0) {
world.append((char) ('`' + num));
}
}

System.out.println(hello + " " + world);

最佳实践

生成特定字符串的种子

如果需要生成特定的字符串,可以编写程序来搜索合适的种子值。以下是一个简单的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.util.Random;

public class SeedFinder {
public static long generateSeed(String goal, long start, long finish) {
char[] input = goal.toCharArray();
char[] pool = new char[input.length];
label:
for (long seed = start; seed < finish; seed++) {
Random random = new Random(seed);

for (int i = 0; i < input.length; i++)
pool[i] = (char) (random.nextInt(27) + '`');

if (random.nextInt(27) == 0) {
for (int i = 0; i < input.length; i++) {
if (input[i] != pool[i])
continue label;
}
return seed;
}
}

throw new NoSuchElementException("Sorry :/");
}

public static void main(String[] args) {
String goal = "hello";
long seed = generateSeed(goal, Long.MIN_VALUE, Long.MAX_VALUE);
System.out.println("Seed for \"" + goal + "\" found: " + seed);
}
}

常见问题

为什么使用相同的种子会生成相同的随机数序列?

Random 类是基于特定的算法和种子值来生成随机数的。当使用相同的种子值时,算法的初始状态相同,因此会生成相同的随机数序列。

如何生成不同的随机数序列?

可以使用当前时间作为种子值,例如 new Random(System.currentTimeMillis()),这样每次运行程序时都会得到不同的随机数序列。

是否可以预测 Random 生成的随机数?

由于 Random 是伪随机数生成器,理论上如果知道种子值和算法,就可以预测后续的随机数。因此,在安全敏感的场景中,应使用 SecureRandom 类。


Java中使用随机字符串代码打印'hello world'的原因解析
https://119291.xyz/posts/2025-04-24.java-random-string-hello-world-explanation/
作者
ww
发布于
2025年4月24日
许可协议