此发生器基于空间数组, 随机种子来自于 time 时间戳末尾位

随着 random 次数增加, array 不确定度持续叠加, 每位概率会有一定波动但不会出现偏倚或黑洞

熵来自于每次 update 的位置和次序, 淡化了某时刻 timestamp 和算力的影响

思想类似卷积, 把过去与当前状态持续叠加到对未来的影响中

  • 现有缺陷

    1. 无法保证 恒定的概率 或者说 等概率随机, 但可以近似做到 自然随机
    2. array 需要预热, 预热效果也会影响一定范围内的随机数质量
    3. 小批量随机效果贼差

分割线

代码

from datetime import datetime

array = [i for i in range(10)]


def random():
time_str = str(datetime.now().timestamp())
if len(time_str) == 16: index = 0
else:
index = int(time_str[-1])

# core: 每次 random, 使 index 位加上下一位的数字
array[index] = (array[index] + array[(1 + index) % len(array)]) % 10

return array[index]


def measure(random_times):
times = [0 for _ in range(10)]
for i in range(random_times):
num = random()
times[num] += 1

random_times_div_10 = random_times // 10
if i % random_times_div_10 == 0:
for i in range(10):
times[i] = times[i] / random_times_div_10
print(times)
times = [0 for _ in range(10)]


if __name__ == '__main__':
# print(random())

# 数量太小, 算力太大把随机度给淹了
print("1K 个随机数 0-9 平均概率:")
measure(1_000)

print()

print("1M 个随机数 0-9 平均概率:")
measure(1_000_000)

1K 个随机数 0-9 平均概率:
[0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]

1M 个随机数 0-9 平均概率:
[0.0, 0.0, 0.0, 1e-05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.08707, 0.09659, 0.07117, 0.09658, 0.08152, 0.11249, 0.08783, 0.15348, 0.07114, 0.14213]
[0.07329, 0.09794, 0.08054, 0.11958, 0.08392, 0.09796, 0.07334, 0.10519, 0.08776, 0.18048]
[0.11594, 0.10057, 0.09201, 0.12211, 0.05934, 0.10781, 0.05929, 0.10423, 0.08083, 0.15787]
[0.11348, 0.09361, 0.09942, 0.09361, 0.08974, 0.11739, 0.1132, 0.09622, 0.08972, 0.09361]
[0.09697, 0.08811, 0.07557, 0.13141, 0.0873, 0.10951, 0.07558, 0.08811, 0.09013, 0.15731]
[0.09858, 0.07631, 0.11606, 0.07633, 0.13287, 0.07633, 0.09857, 0.09382, 0.1125, 0.11863]
[0.07433, 0.12053, 0.07844, 0.11426, 0.07381, 0.11784, 0.09136, 0.12198, 0.09004, 0.11741]
[0.07852, 0.09592, 0.11335, 0.12832, 0.0749, 0.09957, 0.07491, 0.12733, 0.07851, 0.12867]
[0.07114, 0.11785, 0.08166, 0.15484, 0.06758, 0.11358, 0.06757, 0.12409, 0.09167, 0.11002]

分割线

位运算数值分布

print("XOR:")
for i in range(10):
arr = []

for j in range(10):
arr.append(j ^ i)

print(arr)

print("OR:")
for i in range(10):
arr = []

for j in range(10):
arr.append(j | i)

print(arr)
# 产生 '7' 黑洞 (array 内都是 7)
# 10M 个随机数 0-9 平均概率:
# [0.0, 0.0, 0.0, 0.0, 0.0, 1e-06, 0.0, 0.0, 0.0, 0.0]
# [0.0, 1.6e-05, 0.0, 0.035234, 0.0, 6e-06, 0.0, 0.933694, 0.0, 0.03105]
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]

print("AND:")
for i in range(10):
arr = []

for j in range(10):
arr.append(j & i)

print(arr)
# 产生 '0' 黑洞 (array 内都是 0)
# 10M 个随机数 0-9 平均概率:
# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-06, 0.0, 0.0, 0.0]
# [0.992248, 0.0, 0.002597, 0.0, 0.000949, 0.0, 0.001722, 0.0, 0.002484, 0.0]
# [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
XOR:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 0, 3, 2, 5, 4, 7, 6, 9, 8]
[2, 3, 0, 1, 6, 7, 4, 5, 10, 11]
[3, 2, 1, 0, 7, 6, 5, 4, 11, 10]
[4, 5, 6, 7, 0, 1, 2, 3, 12, 13]
[5, 4, 7, 6, 1, 0, 3, 2, 13, 12]
[6, 7, 4, 5, 2, 3, 0, 1, 14, 15]
[7, 6, 5, 4, 3, 2, 1, 0, 15, 14]
[8, 9, 10, 11, 12, 13, 14, 15, 0, 1]
[9, 8, 11, 10, 13, 12, 15, 14, 1, 0]
OR:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 1, 3, 3, 5, 5, 7, 7, 9, 9]
[2, 3, 2, 3, 6, 7, 6, 7, 10, 11]
[3, 3, 3, 3, 7, 7, 7, 7, 11, 11]
[4, 5, 6, 7, 4, 5, 6, 7, 12, 13]
[5, 5, 7, 7, 5, 5, 7, 7, 13, 13]
[6, 7, 6, 7, 6, 7, 6, 7, 14, 15]
[7, 7, 7, 7, 7, 7, 7, 7, 15, 15]
[8, 9, 10, 11, 12, 13, 14, 15, 8, 9]
[9, 9, 11, 11, 13, 13, 15, 15, 9, 9]
AND:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
[0, 0, 2, 2, 0, 0, 2, 2, 0, 0]
[0, 1, 2, 3, 0, 1, 2, 3, 0, 1]
[0, 0, 0, 0, 4, 4, 4, 4, 0, 0]
[0, 1, 0, 1, 4, 5, 4, 5, 0, 1]
[0, 0, 2, 2, 4, 4, 6, 6, 0, 0]
[0, 1, 2, 3, 4, 5, 6, 7, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 0, 8, 8]
[0, 1, 0, 1, 0, 1, 0, 1, 8, 9]

分割线

golang-验证码-随机数生成

最好不要用 rand.intn(), 位数太大时会溢出, 可以用递归来生成无限长的随机数 [1]

func GetRandNum(digit int) (res string) {
if digit < 1 {
return ""
}
if digit < 10 {
// int32 封顶 2^9, 2^10 会溢出
num := rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(int32(Pow10(digit)))
res = fmt.Sprintf("%0"+strconv.Itoa(digit)+"v", num)
} else {
num := rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(int32(Pow10(9)))
res = fmt.Sprintf("%09v", num) + GetRandNum(digit-9)
}
return
}

func GetVerifyCode() string {
return GetRandNum(6)
}

借物表

[1]: Golang/rand.go at master · Weidows/Golang