基于SHA256哈希取模生成的[0,x]区间数值是否服从均匀分布?
问题描述
我实现了一个根据给定字符串生成[0,x]区间内数值的函数,代码如下:
import org.apache.commons.codec.digest.DigestUtils; import java.math.BigInteger; public class BaseUtil { public static int getIntValue(String stringText, String x) { var modNum = new BigInteger(x); String sha256hex = DigestUtils.sha256Hex(stringText); var result = new BigInteger(sha256hex, 16); int intValue = result.mod(modNum).intValue(); return intValue; } }
请问当输入大量随机字符串时,返回的intValue是否在[0,x]区间内服从均匀分布?
解答结论
- 首先注意区间误差:你代码实际返回的数值区间是
[0, x-1],并非你预期的[0, x]。如果需要生成闭区间[0, x]的整数,需要将入参的modNum修改为new BigInteger(x).add(BigInteger.ONE)。 - 均匀性层面:绝大多数业务场景下,返回值可以认为服从均匀分布,统计偏差小到完全可以忽略。
原理说明
SHA256是工业界广泛使用的密码学哈希函数,核心特性之一就是对于随机输入,输出的256位比特序列服从均匀分布,每一位取0或1的概率均为50%,且不同比特之间相互独立。
- 代码中把SHA256的十六进制结果转为BigInteger后,这个值在
[0, 2^256 - 1]区间是完全均匀分布的。 - 对均匀分布的大整数做模x运算时,只有当
2^256不是x的整数倍时才会存在微小偏差:假设2^256 = k * x + r(其中0 ≤ r < x),那么[0, r-1]这r个值的出现概率会比其他值高1/2^256。 - 这个偏差的量级极低,只要x远小于
2^256(比如x小于10^18,已经远超过绝大多数业务场景的x取值上限),偏差在实际使用中完全感知不到,不会对业务造成任何影响。只有当x的大小接近2^256时,偏差才会明显到需要专门处理。
内容的提问来源于stack exchange,提问作者DachuanZhao
相关产品推荐
相关产品推荐

