33 lines
1008 B
Python
33 lines
1008 B
Python
#!/usr/bin/env python3
|
|
|
|
from math import erfc, sqrt
|
|
|
|
|
|
def monobit_test(bitseq: str):
|
|
"""
|
|
Frequency (Monobit) Test for a binary sequence. This tests count the number of '1' and '0' in a bit sequence and make a test statistics
|
|
|
|
This test is based on the NIST SP 800-22 document, that describe how to perform tests for PRNG algorithms:
|
|
https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-22r1a.pdf
|
|
|
|
Returns:
|
|
p_value (float): larger p-values suggest consistency with randomness.
|
|
"""
|
|
|
|
n = len(bitseq)
|
|
if n == 0:
|
|
raise ValueError("bitseq must not be empty")
|
|
|
|
if any(c not in "01" for c in bitseq):
|
|
raise ValueError("bitseq must contain only '0' and '1'")
|
|
|
|
# Count ones and zeros via +/-1 sum
|
|
s = sum(1 if c == "1" else -1 for c in bitseq)
|
|
|
|
# Compute the test statistic
|
|
sobs = abs(s) / sqrt(n)
|
|
|
|
# Compute p-value, based on the Complementary Error Function (erfc)
|
|
p_value = erfc(sobs / sqrt(2))
|
|
return p_value
|