2023-05-09 11:47:12 +02:00
|
|
|
from math import fabs as fabs
|
|
|
|
from math import sqrt as sqrt
|
|
|
|
from scipy.special import erfc as erfc
|
2023-05-15 15:39:31 +02:00
|
|
|
import numpy as np
|
|
|
|
from scipy import stats
|
2023-05-09 11:47:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
class StartUPTest:
|
|
|
|
|
|
|
|
@staticmethod
|
2023-05-15 15:39:31 +02:00
|
|
|
def monobit_test(binary_data: bytes):
|
|
|
|
length_of_bit_string = len(binary_data) * 8
|
2023-05-09 11:47:12 +02:00
|
|
|
|
|
|
|
# Variable for S(n)
|
|
|
|
count = 0
|
2023-05-15 15:39:31 +02:00
|
|
|
# Iterate each byte in the string and compute for S(n)
|
|
|
|
for byte in binary_data:
|
|
|
|
# Iterate each bit in the byte
|
|
|
|
for i in range(8):
|
|
|
|
# Extract the i-th bit from the byte
|
|
|
|
bit = (byte >> i) & 1
|
|
|
|
if bit == 0:
|
|
|
|
# If bit is 0, then -1 from the S(n)
|
|
|
|
count -= 1
|
|
|
|
else:
|
|
|
|
# If bit is 1, then +1 to the S(n)
|
|
|
|
count += 1
|
2023-05-09 11:47:12 +02:00
|
|
|
|
|
|
|
# Compute the test statistic
|
|
|
|
sObs = count / sqrt(length_of_bit_string)
|
|
|
|
|
|
|
|
# Compute p-Value
|
|
|
|
p_value = erfc(fabs(sObs) / sqrt(2))
|
|
|
|
|
|
|
|
# return a p_value and randomness result
|
|
|
|
return p_value, (p_value >= 0.01)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def autocorrelation_test(binary_data: str):
|
|
|
|
|
|
|
|
shift_feld = [0] * 5000
|
|
|
|
max_korr_feld = [0] * 5000
|
|
|
|
|
|
|
|
# Fill BitFeldB with data
|
|
|
|
|
|
|
|
for tau in range(1, 5001):
|
|
|
|
z_tau = 0
|
|
|
|
for i in range(5000):
|
|
|
|
z_tau += binary_data[i] ^ binary_data[i + tau]
|
|
|
|
shift_feld[tau - 1] = z_tau
|
|
|
|
|
|
|
|
# Debugging
|
|
|
|
# for i in range(5000):
|
|
|
|
# print(shift_feld[i], end=' ')
|
|
|
|
|
|
|
|
# Find the index of the maximum deviation from 2500
|
|
|
|
max_deviation = 0
|
|
|
|
for tau in range(5000):
|
|
|
|
deviation = abs(shift_feld[tau] - 2500)
|
|
|
|
if deviation > max_deviation:
|
|
|
|
max_deviation = deviation
|
|
|
|
|
|
|
|
# Find all indices with the maximum deviation
|
|
|
|
j = 0
|
|
|
|
for tau in range(5000):
|
|
|
|
deviation = abs(shift_feld[tau] - 2500)
|
|
|
|
if deviation == max_deviation:
|
|
|
|
max_korr_feld[j] = tau
|
|
|
|
j += 1
|
|
|
|
|
|
|
|
print("Maximale z_tau-Abweichung von 2500:", max_deviation)
|
|
|
|
print("Aufgetreten für Shifts:")
|
|
|
|
for k in range(j):
|
|
|
|
print("Shift:", max_korr_feld[k] + 1)
|
|
|
|
|
|
|
|
tau = max_korr_feld[0]
|
|
|
|
z_tau = 0
|
|
|
|
for i in range(10000, 15000):
|
|
|
|
z_tau += StartUPTest.char_to_int(i, binary_data) ^ StartUPTest.char_to_int(i + tau + 1, binary_data)
|
|
|
|
tau += 1
|
|
|
|
|
|
|
|
ok = 2326 < z_tau < 2674
|
|
|
|
return z_tau, ok
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def char_to_int(index, binary_data: str):
|
|
|
|
if binary_data[index] == 49:
|
|
|
|
value = 1
|
|
|
|
else:
|
|
|
|
value = 0
|
|
|
|
return value
|
2023-05-15 15:39:31 +02:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def chi_square(byte_data: bytes):
|
|
|
|
expected_probabilities = np.full(256, 1/256) # Assuming 256 possible byte values
|
|
|
|
total_observations = len(byte_data)
|
|
|
|
observed_data, _ = np.histogram(list(byte_data), bins=np.arange(257))
|
|
|
|
expected_frequencies = expected_probabilities * total_observations
|
|
|
|
|
|
|
|
chi2_statistic, p_value = stats.chisquare(observed_data, f_exp=expected_frequencies)
|
|
|
|
|
|
|
|
return p_value, (p_value >= 0.01), chi2_statistic
|