1.简介
LFSR(线性反馈移位寄存器),可以生成伪随机序列,用于数据压缩,数据加解密等。 一般采用verilog等硬件描述语言实现,此处使用python描述其行为,有些地方写法较生硬,可作为硬件生成序列的一个比对参考。
2.实现
以图1为例(verilog实现见https://blog.csdn.net/limanjihe/article/details/52400969),
n=8:D7~D0,反馈系数如图蓝色标示从右到左(高位到低位)为“101110001”,除图上最左边和最右边的‘1’外,其余各位可看成是否进行异或操作的指示。从反馈系数的左数第二位开始取,同时把D0的反馈系数置零,得到实际的异或指示为:“01110000”,分别对应D7~D0的系数。
定义输入:
array_init = 255 #多项式初值,设为十进制255
tap_init = "101110000" #LFSR抽头,已将D0系数置零
tap = tap_init[1:] #从第2位开始取,为实际的异或指示“01110000”
把输入转化为8位二进制,注意“08b”的‘0’不能省略,以保证高位为0时仍然是8位数:
array_init_bin = '{:08b}'.format(array_init)
定义输出,由于python不支持直接对字符串的某位赋值,而list可以。此处先将输出转成list,处理完后在转回字符串:
array_new = '0'*len(array_init_bin)
array_new = list(array_new) #转为list,以对字符串位进行赋值
开始移位并异或反馈,注意array[0:7]与图1的D7~D0对应:
for i in range(len(array_init_bin)): #对每位进行操作,D6->D7、D5->D6、D4->D5...
j = i+1
if(i == (len(array_init_bin)-1)): #array[0]-->array[7],即D7-->D0,
j = 0
if(tap[i]=='1'): #‘1’表示需进行异或操作,Dx^D7
array_new[i] = str(int(array_init_bin[j])^int(array_init_bin[0]))
else:
array_new[i] = str(array_init_bin[j])
array_new = ''.join(array_new) #将list转回字符串
最终由“11111111”得到了第二轮array:“10001111”。
将其定义成def,然后循环调用,可以得到更多序列,完整代码如下:
def lfsr(ai,t):
array_init = ai#255 #多项式
tap_init = t#"101110000"#抽头
tap = tap_init[1:]
array_init_bin = '{:08b}'.format(array_init)
array_new = '0'*len(array_init_bin)
array_new = list(array_new)
for i in range(len(array_init_bin)):
j = i+1
if(i == (len(array_init_bin)-1)):
j = 0
if(tap[i]=='1'):
array_new[i] = str(int(array_init_bin[j])^int(array_init_bin[0]))
else:
array_new[i] = str(array_init_bin[j])
array_new = ''.join(array_new)
print(array_new) #二进制
print(int(array_new,2)) #十进制
print(hex(int(array_new,2))) #十六进制
with open('test.txt', 'a+') as f: #写入txt
f.write(str(hex(int(array_new,2)))+'\n')
return int(array_new,2)
#调用20次
init = 255
tap = "101110000"
for i in range(20):
init = lfsr(init,tap)
网友评论