随机数生成
CSPRNG 加拒绝采样消除取模偏置,支持区间与不重复。
随机源用的是浏览器的 Web Crypto:crypto.getRandomValues 从操作系统的熵池(Windows 的 BCryptGenRandom、Linux 的 getrandom)取 32 位无符号整数,每次批量取 8 个缓存复用。它替代的是 Math.random——后者是 xorshift128+ 之类的非加密生成器,只要观察到连续两次输出就能反推内部状态、预测后续所有数字,而且它的输出只有 53 位精度、步进固定,长序列存在可复现的规律。需要「别人猜不到」的场合(抽奖、验证码、抽样名单、测试用的 ID)都应该用 CSPRNG,这也是本工具只走 Web Crypto 的原因。要注意区分的是:getRandomValues 不是确定性流加密,不能当密钥派生使用,长期密钥请交给 Web Crypto 的 generateKey。
有界随机数不能直接取模。2³² 一般不能被区间长度 n 整除,「x % n」会把 2³² 个原始值不均匀地摊到 n 个结果上,前 2³² mod n 个结果各多出一档概率:最经典的例子是 8 位随机数 0–255 对 10 取模,0 到 5 各有 26 个原像、6 到 9 只有 25 个,0 的出现概率比 9 高约 4%。工具用拒绝采样消除这个偏置:先算 limit = 2³² − (2³² mod n),落在 [limit, 2³²) 这段「尾巴」上的读数整轮丢弃重取,剩下的正好是 n 的整数倍,每个值的概率严格相等。代价小到可以忽略:区间长度 100 时只有 2.2 × 10⁻⁸ 的读数会被丢弃(约四千万次采样一次),即便把区间放宽到 −10 亿到 10 亿,拒绝率也只有 6.9%,平均 1.07 次采样出一个数;输出区下方会写明本次区间的实际拒绝率与平均采样次数。区间 [min, max] 是闭区间,两个端点都取得到;数量 1–1000;打开「不重复」后按区间容量自动选择集合重试或部分 Fisher–Yates 洗牌,装不下会直接报错而不是悄悄少给。
随机数生成怎么用
- 抽 N 个整数:默认在 1–100 里生成 10 个,可把最小/最大调到 ±10 亿,数量最多 1000 个;结果一行一个,方便直接粘进表格或脚本。
- 抽奖与抽样名单:打开「不重复」再配合「结果升序」,就是 N 个互不相同且有序的中签号;如果区间里可取的数不够(例如 1–5 要 6 个不重复),会明确报错说明容量只有多少个。
- 测试数据与模拟:把区间设为 −100 到 100 生成误差项,或 0 到 1 生成开关位;需要可复现的固定序列时,本工具不适用——它没有种子输入,每次都不同。
常见问题
Math.floor(Math.random() * (max - min + 1)) + min 有什么问题?网上都这么写。
它有两个问题。第一是偏置:Math.random 大约给出 2⁵³ 个均匀值,映射到 n 个结果时同样有 (2⁵³ mod n) 个原像多出一档,n 不整除样本空间时概率就不相等,取模写成 Math.random() * n | 0 或 rand % n 是同一个毛病,只是更明显。第二是随机源:Math.random 不是密码学安全的,V8 的 xorshift128+ 只要拿到两个连续输出就能恢复 128 位内部状态,之后生成的所有数都能预测。拒绝采样解决前者(丢弃尾部区间,剩余概率精确相等),Web Crypto 解决后者。
拒绝采样会不会一直重取、卡住不动?
不会。被拒绝的概率是 (2³² mod n) / 2³²,它的上界是 n / 2³²,所以在工具允许的区间里最大也就百分之几(−10 亿到 10 亿时约 6.9%),平均 1.07 次采样出一个数,区间越短还越低(1–100 约 2.2 × 10⁻⁸);本工具一次取 8 个 32 位整数缓存复用,只有真正需要时才向系统要更多熵,循环次数不可能失控。真正可能变慢的是「不重复」模式:当 count 接近区间容量时,随机撞车的期望尝试次数按 n/(n−k) 增长,所以工具在容量不超过 262144 且抽取比例超过 1/8 时改用部分 Fisher–Yates 洗牌(只洗前 count 位,保证等概率且不重复),用集合重试时也给了显式预算(约 500 × count 次尝试),超预算就报错提示减小数量或放宽区间,绝不无限循环。
生成的数能当密码、验证码或抽奖结果吗?能复现吗?
抽奖、抽样、测试数据都可以,因为这些场景要的是「不可预测且均匀」。但别把它当密钥或口令:getRandomValues 提供的是熵源而非经过认证的 DRBG,口令还应满足长度与字符集要求,本工具不校验熵位。可复现性则是刻意没有——不接受种子,所以同一参数每次运行结果都不同;需要「同一份数据反复跑测试」时请用带种子的伪随机库,并在报告里记下种子。另外它只在本地生成,不上传、不落盘,刷新页面就没了。