print("\n# CHAP09 -- Python-Script-SAMPLE 153: =========")
print("---------- Apply LFSR using Python package pyLFSR ----------")
# Output sequence by pyLFSR using state = [0,0,1,1,1,0,0,1] and fpoly = [8,6,4,3]
# - script creates the same result as CT2, which needs fpoly and state just in reversed order.
# - see https://lfsr.readthedocs.io/en/latest/dispViz.html

from pylfsr import LFSR

# Give bitsequence for seed as in CT2; reverse it and offer it as list for pyLFSR .......
seed = '10011100'  # seed here is a string. This bit sequence is given in CT2 as state.
width = len(seed)  # length of register
num = int(seed, 2)  # you also could enter it directly as 0b10011100 or 15 or 0x15 or 0xAAAA

output = [int(x) for x in '{:0{size}b}'.format(num, size=width)]  # width for potentially leeding bits
print('1a: given seed    =', output)
output.reverse()  # reverse, as pyLFSR needs state in reverse order as CT2
print('1b: reversed seed =', output)
state = output  # state = seed = initial value
statecheck = [0,0,1,1,1,0,0,1]; assert state == statecheck

# Give bitsequence for tap sequence as in CT2; create list of polynomial orders for pyLFSR .......
fpoly = '00110101'  # tap sequence
num = int(fpoly, 2)
output = [int(x) for x in '{:0{size}b}'.format(num, size=width)]
print('2a: fpoly = ', output)
fpoly = [i+1 for i, val in enumerate(output) if val]
fpoly.reverse()
print("2b: fpoly = ",fpoly)
fpolycheck = [8,6,4,3]; assert fpoly == fpolycheck

# Calculate the binary LFSR output sequence
L = LFSR(initstate=state,fpoly=fpoly,counter_start_zero=True)
print('-'*50)
print('count \tstate \t\t\t\toutbit \tseq')
print('-'*50)
for _ in range(15):
    print(L.count,L.state,'',L.outbit,L.seq,sep='\t')
    L.next()
print('-'*50)
print('Output: ',L.seq)

# --------------------------------------------------
# CHAP09 -- Python-Script-SAMPLE 153: =========
# ---------- Apply LFSR using Python package pyLFSR ----------
# 1a: given seed    = [1, 0, 0, 1, 1, 1, 0, 0]
# 1b: reversed seed = [0, 0, 1, 1, 1, 0, 0, 1]
# 2a: fpoly =  [0, 0, 1, 1, 0, 1, 0, 1]
# 2b: fpoly =  [8, 6, 4, 3]
# --------------------------------------------------
# count   state                           outbit  seq
# --------------------------------------------------
# 0       [0 0 1 1 1 0 0 1]               -1      [-1]
# 1       [1 0 0 1 1 1 0 0]               1       [1]
# 2       [0 1 0 0 1 1 1 0]               0       [1 0]
# 3       [1 0 1 0 0 1 1 1]               0       [1 0 0]
# 4       [1 1 0 1 0 0 1 1]               1       [1 0 0 1]
# 5       [0 1 1 0 1 0 0 1]               1       [1 0 0 1 1]
# 6       [0 0 1 1 0 1 0 0]               1       [1 0 0 1 1 1]
# 7       [1 0 0 1 1 0 1 0]               0       [1 0 0 1 1 1 0]
# 8       [1 1 0 0 1 1 0 1]               0       [1 0 0 1 1 1 0 0]
# 9       [0 1 1 0 0 1 1 0]               1       [1 0 0 1 1 1 0 0 1]
# 10      [0 0 1 1 0 0 1 1]               0       [1 0 0 1 1 1 0 0 1 0]
# 11      [1 0 0 1 1 0 0 1]               1       [1 0 0 1 1 1 0 0 1 0 1]
# 12      [0 1 0 0 1 1 0 0]               1       [1 0 0 1 1 1 0 0 1 0 1 1]
# 13      [1 0 1 0 0 1 1 0]               0       [1 0 0 1 1 1 0 0 1 0 1 1 0]
# 14      [0 1 0 1 0 0 1 1]               0       [1 0 0 1 1 1 0 0 1 0 1 1 0 0]
# --------------------------------------------------
# Output:  [1 0 0 1 1 1 0 0 1 0 1 1 0 0 1]
