0

我正在尝试实现NIST Spectral Test(第 2.6 节)来测试 Python 中随机数生成器的随机性。该测试利用离散傅立叶变换来查找生成的比特流中的周期性趋势。我的代码如下所示:

from numpy import abs
from math import sqrt, log, erfc
from scipy.fft import fft

# ...

def nist_spectral_test(self):
    binary_data = [1,1,0,0,1,0,0,1,0,0,0,0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,1,0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,0,0,1,0,1,0,0,0,1,0,1,1,1,0,0,0]
    n = len(binary_data)
    X = [2*e-1 for e in binary_data]
    S = fft(X)
    M = [abs(s) for s in S[:n//2]]
    T = sqrt(log(1/0.05) * n)
    N0 = 0.95 * n / 2
    N1 = 0
    for m in M:
        if m < T:
            N1 += 1
    d = (N1 - N0) / (sqrt(n * 0.95 * 0.05 / 4))
    p_val = erfc(abs(d)/sqrt(2))
    print(f'N0: {N0}\nN1: {N1}\nT: {T}\nd: {d}\np value: {p_val}')

binary_data列表被硬编码用于演示目的,取自上面链接的 NIST 文档第 2.6.8 节。变量名称遵循所述文档的命名。

当我运行这段代码时,我得到了结果

N0: 47.5
N1: 48
T: 17.30818382602285
d: 0.4588314677411235
p value: 0.6463551955394902

而不是第 2.6.8 节中显示的预期结果

N0: 47.5
N1: 46
d: -1.376494
p value: 0.168669

这意味着我在计算时在某处犯了错误N1。我的问题是我不知道在哪里。我试图四处寻找这个测试的实现,但我只找到了这个,它返回的结果与我的代码完全相同。

我在哪里犯了错误?我是否在任何时候误解了参考文档,或者我是否滥用了任何导入的数学函数/库?

4

0 回答 0