为何这个生成随机整数的简单Go函数可以正常工作?
这段Go伪随机数函数的工作原理解析
你贴出的代码是**线性同余生成器(Linear Congruential Generator, LCG)**的实现,这是一种经典的伪随机数生成算法,早年广泛应用在UNIX系统、C标准库的rand()函数中。
核心算法逻辑
LCG的通用公式是:
next_state = (current_state * 乘数 + 增量) % 模数
对应到你的代码:
- 全局变量
r是生成器的状态变量,保存当前的计算状态,每次生成新数后会更新 - 固定乘数是
1103515245,增量是12345——这两个是POSIX标准规定的参数,用来保证生成序列的统计均匀性 - 代码里用
r & 0x7fffffff代替取模运算:0x7fffffff是31位全1的二进制数,和它做按位与运算,等价于对2^31取模,能把结果限制在0到2^31-1的正整数范围(避免Go中int类型出现负数)
逐行代码解释
var r = 12345:这是生成器的初始种子,决定了整个随机序列的起点。种子固定的话,每次运行生成的序列完全一致。func rand() int:生成下一个伪随机数的入口函数r = r*1103515245 + 12345:按照LCG公式更新状态,用当前状态计算出下一个状态值return r & 0x7fffffff:截断状态值为31位正整数,作为最终返回的随机数
关于参数的选择
1103515245和12345不是随意设定的,它们是经过验证的LCG参数,能让生成的序列达到最长周期(对于31位LCG来说周期可达2^31),同时保证序列的均匀分布特性,避免出现明显的重复或偏斜。
关于加密安全性
你提到的「该函数不具备加密安全性」完全正确:
- LCG的序列可预测性极强:只要获取到序列中连续的几个值,就能反推出种子,进而精准预测后续所有随机数
- 周期有限,且序列的统计特性容易被破解,完全不适合加密、密码学相关场景
性能特性(补充参考)
LCG的性能非常出色,仅包含简单的乘法、加法和位运算,没有复杂计算,适合对性能要求高但对随机性要求一般的场景(比如简单模拟、非安全的随机抽样等)。
内容的提问来源于stack exchange,提问作者DrGo
相关产品推荐
相关产品推荐

