种子随机:线性同余生成器(LCG, Linear Congruential Generator)

Janing

线性同余生成器

实现代码:

1
2
3
4
5
6
7
8
9
10
Math.seed = 5;
Math.seededRandom = function(max, min) {
max = max || 1;
min = min || 0;

Math.seed = (Math.seed * 9301 + 49297) % 233280;
var rnd = Math.seed / 233280.0;

return Math.ceil( min + rnd * (max - min) ); // Math.ceil实现取整功能,可以根据需要取消取整
};

本文的重点是:(Math.seed * 9301 + 49297) % 233280,为什么会是这三个值,而不是其它的到底这三个数字有什么神秘的来历呢?

像 Math.seededRandom 这种伪随机数生成器叫做线性同余生成器(LCG, Linear Congruential Generator),几乎所有的运行库提供的 rand 都是采用的LCG,形如:

In+1=aIn+c(mod m)

生成的伪随机数序列最大周期m,范围在 0 到 m-1 之间。要达到这个最大周期,必须满足:

c与m互质
a - 1可以被m的所有质因数整除
如果m是4的倍数,a - 1也必须是4的倍数
以上三条被称为Hull-Dobell定理。作为一个伪随机数生成器,周期不够大是不好意思混的,所以这是要求之一。因此才有了:a=9301, c = 49297, m = 233280这组参数,以上三条全部满足。

字母种子

由于数字0~9可以表示十进制,而加上a-z刚好是36进制,在这个区间内可以实现字母+数字的种子。

实现:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const NUM36 = "0123456789abcdefghijklmnopqrstuvwxyz"

/**生成随机种子 */
function GenSeed(len) {
let result = []
for (let i = 0; i < len; i++) {
let index = Math.floor(Math.random() * NUM36.length)
result.push(NUM36.charAt(index))
}
return result.join("")
// return Math.random().toString(36).substr(2)
}

/**十进制数转成36进制 */
function ConvertTo36(n) {
var arr = [];
var nums36 = NUM36;
var neg = n < 0
n = Math.abs(Math.floor(n))
while (n) {
//除n取余
var res = n % 36;
//然后作为下标得到对应的36进制数
arr.unshift(nums36[res]);
//去掉个位
n = parseInt(n / 36);
}
if (neg) {
arr.unshift("-")
}
return arr.join("");
}

/**36进制转十进制 */
function ConvertTo10(n36) {
return parseInt(n36, 36)
}


let seed = genSeed(6)
let n10 = scale10(seed)
let n36 = scale36(n10)
console.log(seed) // fbl2uv
console.log(n10) // 926451895
console.log(n36) // fbl2uv

大数处理

Java作为服务端,经常有部分数字是以64位的形式传递,可能会到19位,JS仅支持16位安全数字。可以先进行取模,再执行随机

1
2
3
4
5
6
let seedOrigin = BigInt(3327170722379824600)
let n10 = Number(seedOrigin % BigInt(Number.MAX_SAFE_INTEGER))
let n36 = ConvertTo36(n10)
console.log(seedOrigin) // 3327170722379824640
console.log(n10) // 3514197380398961
console.log(n36) // ylofzmegz5
  • Title: 种子随机:线性同余生成器(LCG, Linear Congruential Generator)
  • Author: Janing
  • Created at : 2025-09-25 20:16:00
  • Updated at : 2025-09-25 20:34:14
  • Link: https://your-domain.com/种子随机:线性同余生成器(LCG, Linear Congruential Generator)/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
种子随机:线性同余生成器(LCG, Linear Congruential Generator)