均匀分布的长周期线性
Well Equidistributed Long-period Linear (WELL)是一种基于线性反馈移位寄存器技术的伪随机数生成算法,用于创建伪随机数。它属于线性同余生成器家族。它在功能方面类似于梅森捻线器,因为它们都使用 XOR、移位和 LFSR 机制工作。两者都需要一个种子值来开始生成过程。
伪随机数生成器是指一类算法,它利用一组初始种子值并应用各种逻辑运算或移位运算来产生看似随机的数。生成器可以递归定义如下:
Xn+1 = (a*(Xn) + c) modulo-m
where X is a sequence of pseudorandom values,
m is the modulus (m>0),
a is the multiplier (0
算法如下:
0. Initialize the necessary seed values
1. Utilize a state array of a defined length (here it is 32)
2. Apply the necessary xor, shift and logical and operations to arrive at
the required parameters
3a. Update the current location value and output that value from an array
location multiplied with a scaling constant
3b. newV0 and newV1 are additional pseudorandom numbers that can be supplied
as per requirement
WELL算法可以在短时间内产生很多数字,对于需要很多数字的应用来说是有利的。 WELL 的主要弱点之一是状态空间较小。这可以通过利用更大尺寸的状态空间来改变,而辅助空间被折衷。
Python代码实现——
# W stands for size of the digest, R is the size of the state
W = 32;R = 32
# Variables used for jumping to a particular state
M1 = 3;M2 = 24;M3 = 10
# can be changed to scale accordingly
FACT = 1.718
# value based right shift with xor operation
def mat0pos(t, v):
return(v^(v>>t))
# value based negative left shift with xor operation
def mat0neg(t, v):
return(v^(v<<(~t)))
# returns the value itself (identity function)
def identity(v):
return v
state = [None]*R
state_i = 0; z0 = None;z1 = None;z2 = None; newV1 = None; newV0 = None
# used to initialize the state of our digest based on argument provided
def InitWellRNG(arg):
global state
for j in range(0, len(arg)):
state[j]= arg[j]
# function that utilizes seed values and logical operations to
# output random numbers
def WELLRNG():
global state_i
global z0; global z1; global z2; global newV1; global newV0
z0 = state[(state_i + M1) & 0x001f]
z1 = identity(state[state_i]) ^ mat0pos(8, state[(state_i + M1) & 0x001f])
z2 = mat0neg(-19, state[(state_i + M2) & 0x001f]) ^ mat0neg(-14,
state[(state_i + M3) & 0x001f])
# newV1 and newV0 are additional random values that are produced
# and can be returned as per requirement
newV1 = z1 ^ z2;
newV0 = mat0neg(-11, z0) ^ mat0neg(-7, z1) ^ mat0neg(-13, z2)
state_i = (state_i + (W-1)) & 0x001f
return (state[state_i] *FACT)
# executed if this is the main file
if (__name__ == "__main__"):
print("WELL created\n")
# replace seed array with your own array to create different output
# sequence of random numbers
seed = [27, 10, 14, 27, 24, 4, 11, 25, 14, 13, 2, 20, 0, 22, 9, 24, 14, 9,
20, 14, 17, 6, 21, 10, 27, 8, 16, 5, 26, 21, 18, 29]
InitWellRNG(seed)
for i in range(0,5):
print("random number generated is {}".format(WELLRNG()))
输出 :
WELL created
random number generated is 49.822
random number generated is 30.924
random number generated is 36.078
random number generated is 44.668
random number generated is 8.59