#!/usr/bin/env python3 from random import randint from math import log2 class lfsr(object): def __init__(self, state, taps): self.state = state self.taps = taps # getters and setters (private attributes) def get_state(self): return self.__state def set_state(self, value): self.__state = value state = property(fget=get_state, fset=set_state, doc="lfsr state (current bits value in lfsr)") def get_taps(self): return self.__taps def set_taps(self, valeur): self.__taps = valeur taps = property(fget=get_taps, fset=set_taps, doc="lfsr taps (bit positions affecting next state)") def shift(self): ''' calculate next state and return the output bit ''' feedback = sum(self.state[tap] for tap in self.taps) % 2 output = self.state[-1] self.state = [feedback] + self.state[:-1] return output def test_lfsr17(): key = [randint(0, 1) for _ in range(16)] # first 16 bits key.append(1) # prevent initial state from being {0}^17 taps = [16-0, 16-14] lfsr17 = lfsr(key, taps) states = [lfsr17.state] for _ in range(2**17-2): lfsr17.shift() states.append(lfsr17.state) sorted_states = sorted(states, key=lambda x: tuple(x)) for i in range(2**17-2): if sorted_states[i] == sorted_states[i+1]: # compare each state with the next state in the sorted list, if 2 states are identical they should be next to each other print(f'state {sorted_states[i]} appears at least 2 times') return False n_state = len(sorted_states) n_state_log = log2(n_state+1) print(f'all {n_state} = 2^({n_state_log})-1 states are different') return True test_lfsr17()