1. 程式人生 > 其它 >Berlekamp-Massey演算法及python程式碼實現

Berlekamp-Massey演算法及python程式碼實現

技術標籤:python密碼學

1. Berlekamp-Massey演算法原理介紹

1.1 基本概念簡介

  設 a ‾ = ( a 0 , , a 1 , ⋯   , a N − 1 ) \underline{a}=\left( a_{0,},a_1,\cdots ,a_{N-1} \right) a=(a0,,a1,,aN1) F 2 F_2 F2上的長度為N的序列, F 2 F_2 F2上的多項式為:
f ( x ) = c 0 + c 1 x + c 2 x 2 + ⋯ + c l x l f\left( x \right) =c_0+c_1x+c_2x^2+\cdots +c_lx^l

f(x)=c0+c1x+c2x2++clxl
  其中 c 0 = 1 c_0 = 1 c0=1。如果序列中的元素滿足遞推關係:
a k = c 1 a k − 1 + c 2 a k − 2 + ⋯ + c l a k − l , k = l , l + 1 , ⋯   , N − 1 a_k=c_1a_{k-1}+c_2a_{k-2}+\cdots +c_la_{k-l},k=l,l+1,\cdots ,N-1 ak=c1ak1+c2ak2++clakl,k=l,l+1,,N1
  則稱 < f ( x ) , l > \left< f\left( x \right) ,l \right>
f(x),l
產生二元序列 a ‾ \underline{a} a。其中 < f ( x ) , l > \left< f\left( x \right) ,l \right> f(x),l表示以 f ( x ) f\left( x \right) f(x)為反饋多項式的 l l l級線性移位暫存器。如果 f ( x ) f\left( x \right) f(x)是一個能產生 a ‾ \underline{a} a並且級數最小的線性移位暫存器的反饋多項式, l l l是該移存器的級數,則稱 < f ( x ) , l > \left< f\left( x \right) ,l \right>
f(x),l
為序列 a ‾ \underline{a} a的線性綜合解。
  給定一個N長二元序列 a ‾ \underline{a} a,求能產生 a ‾ \underline{a} a並且級數最小的線性移位暫存器,就是求 a ‾ \underline{a} a的線性綜合解。利用B-M演算法便可以有效地求出。

1.2 B-M演算法流程

  任意給定一個N長序列 a ‾ = ( a 0 , , a 1 , ⋯   , a N − 1 ) \underline{a}=\left( a_{0,},a_1,\cdots ,a_{N-1} \right) a=(a0,,a1,,aN1),規定 f 0 ( x ) = 1 f_0\left( x \right) =1 f0(x)=1是生成序列 a ‾ \underline{a} a的前0位的最低次多項式,假定 f 0 ( x ) , f 1 ( x ) , ⋯   , f n ( x ) f_0\left( x \right) ,f_1\left( x \right) ,\cdots ,f_n\left( x \right) f0(x),f1(x),,fn(x)依次是 a ‾ \underline{a} a的前0位、前1位,……前n位的最低次多項式,其次數分別為 l 0 , l 1 . . . , l n l_0,l_1...,l_n l0,l1...,ln。BM演算法流程如下:
  1、取初始值: f 0 ( x ) = 1 , l 0 = 0 , n = 0 f_0\left( x \right) =1,\quad l_0=0\text{,}n=0 f0(x)=1,l0=0n=0
  2、假設 < f 0 ( x ) , l 0 > , < f 1 ( x ) , l 1 > , ⋯   , < f n ( x ) , l n > \left< f_0\left( x \right) ,l_0 \right> ,\left< f_1\left( x \right) ,l_1 \right> ,\cdots ,\left< f_n\left( x \right) ,l_n \right> f0(x),l0,f1(x),l1,,fn(x),ln均已經求得,下面計算 f n + 1 ( x ) f_{n+1}\left( x \right) fn+1(x)以及 l n + 1 l_{n+1} ln+1。記 f n ( x ) = c 0 ( n ) + c 1 ( n ) x + ⋯ c l n ( n ) x l n , c 0 ( n ) = 1 f_n\left( x \right) =c_{0}^{\left( n \right)}+c_{1}^{\left( n \right)}x+\cdots c_{l_n}^{\left( n \right)}x^{l_n}\text{,}c_{0}^{\left( n \right)}=1 fn(x)=c0(n)+c1(n)x+cln(n)xlnc0(n)=1,再計算:
d n = c 0 ( n ) a n + c 1 ( n ) a n − 1 + ⋯ + c l n ( n ) a n − l n d_n=c_{0}^{\left( n \right)}a_n+c_{1}^{\left( n \right)}a_{n-1}+\cdots +c_{l_n}^{\left( n \right)}a_{n-l_n} dn=c0(n)an+c1(n)an1++cln(n)anln
  (1)若 d n = 0 \boldsymbol{d}_{\boldsymbol{n}}=0 dn=0,即 f n ( x ) f_n\left( x \right) fn(x)能生成 a ‾ \underline{a} a的前n+1項,則令:
f n + 1 ( x ) = f n ( x ) , l n + 1 = l n f_{n+1}\left( x \right) =f_n\left( x \right) ,\quad l_{n+1}=l_n fn+1(x)=fn(x),ln+1=ln
  (2)若 d n = 1 \boldsymbol{d}_{\boldsymbol{n}}=1 dn=1,即 f n ( x ) f_n\left( x \right) fn(x)不能生成 a ‾ \underline{a} a的前n+1項,
    (i)當 l 0 = l 1 = ⋯ = l n = 0 l_0=l_1=\cdots =l_n=0 l0=l1==ln=0時,取 f n + 1 ( x ) = 1 + x n + 1 , l n + 1 = n + 1 f_{n+1}\left( x \right) =1+x^{n+1}\text{,}l_{n+1}=n+1 fn+1(x)=1+xn+1ln+1=n+1

    (ii)當 l m < l m + 1 = l m + 2 = ⋯ = l n l_m<l_{m+1}=l_{m+2}=\cdots =l_n lm<lm+1=lm+2==ln時:
      <1>如果 m − l m ≥ n − l n m-l_m\geq n-l_n mlmnln,那麼取
f n + 1 ( x ) = f n ( x ) − d n d m − 1 x ( m − l m ) − ( n − l n ) f m ( x ) = f n ( x ) + x ( m − l m ) − ( n − l n ) f m ( x ) f_{n+1}\left( x \right) =f_n\left( x \right) -d_nd_{m}^{-1}x^{\left( m-l_m \right) -\left( n-l_n \right)}f_m\left( x \right) =f_n\left( x \right) +x^{\left( m-l_m \right) -\left( n-l_n \right)}f_m\left( x \right) fn+1(x)=fn(x)dndm1x(mlm)(nln)fm(x)=fn(x)+x(mlm)(nln)fm(x)
      <2>如果 m − l m < n − l n m-l_m<n-l_n mlm<nln,那麼取
f n + 1 ( x ) = x ( n − l n ) − ( m − l m ) f n ( x ) − d n d m − 1 f m ( x ) = x ( n − l n ) − ( m − l m ) f n ( x ) + f m ( x ) f_{n+1}\left( x \right) =x^{\left( n-l_n \right) -\left( m-l_m \right)}f_n\left( x \right) -d_nd_{m}^{-1}f_m\left( x \right) =x^{\left( n-l_n \right) -\left( m-l_m \right)}f_n\left( x \right) +f_m\left( x \right) fn+1(x)=x(nln)(mlm)fn(x)dndm1fm(x)=x(nln)(mlm)fn(x)+fm(x)
  3、不斷重複步驟2,直至 n = N − 1 n=N-1 n=N1,最後得到的 < f N ( x ) , l N > \left< f_N\left( x \right) ,l_N \right> fN(x),lN便是產生序列 a ‾ \underline{a} a的最短線性移位暫存器。

2. Python程式碼實現

2.1 程式設計思路

  根據1.2中BM演算法流程,編寫程式的流程圖如下:

2.2 python原始碼

# @ BM演算法求序列的最低次多項式(二元域)
# @ 2020.11.20 
def BM(sequence): 
    f_min = [0]  #最低次多項式 
    l = [0]      #記錄每一次最低次多項式次數 
    for i in range(len(sequence)):
        d = 0           
        for j in f_min:  #計算每一次的d值
            d += sequence[i+j-max(l)]  #mod問題、序列問題
        d = d %2            
        if d == 0:       #d為0時
            l.append(l[i])     
        else:            #d不為0時
            if the_same(l):       #d不為0且l列表中數字相同時
                n = i
                fn = f_min.copy()           #copy問題
                f_min.append(i+1)
                l.append(i+1)
            else:                 #d不為0時且l列表中數字不同時 
                if max(f_min) > max(fn):  #用於記錄m以及fm的值    
                    m = n 
                    fm = fn.copy()
                n = i
                fn = f_min.copy()
                if m-l[m] >= n-l[n]: 
                    f_min += [j+(m-l[m]-n+l[n]) for j in fm]
                else:
                    f_min = [j+(-m+l[m]+n-l[n]) for j in f_min] + fm
                l.append(max(f_min))     
    f_min = condense(f_min)                
    return f_min

def condense(f_min):    #壓縮f多項式,即相同的階數利用二元加法合併排序後返回 
    f = list(set(f_min))
    for i in f_min:
        if f_min.count(i) % 2 ==0:
            if i in f:
                f.remove(i)
    f = sorted(f, reverse=True)        
    return f

def the_same(l):           #判斷l列表中的數字是否全部相同 
    for i in range(len(l)-1):
        if l[i]!=l[i+1]:        
            return False
    return True
 
def print_f(f_min):        #還原多項式字串並返回
    result = ''     
    for i in f_min: 
        if i == 0: 
            result += '1' 
        else: 
            result += 'x^' + str(i) 
        if i != f_min[-1]: 
            result += '+' 
    return result 
 
def Seq2list(sequence):    #將字串轉為int形列表 
    result = [] 
    for i in sequence: 
        result.append(int(i)) 
    return result 

if __name__ == "__main__":
    seq = ['10010000111101000011100000011', '00001110110101000110111100011', '10101111010001001010111100010']
    for S in seq: 
        f_min = BM(Seq2list(S)) 
        print('輸入序列:' + S)  
        print('最低次多項式:' + print_f(f_min)) 
        print('最低次數:' + str(max(f_min))) 
        print(" ")

2.3 注意事項

  本文的BM演算法是定義在二元域上:
   ●在計算d時,需要使用d = d % 2後,在判斷d取值是否為0。
   ● 在輸出結果前需要對f_min進行壓縮,x^n有偶數次則不輸出。

2.4 結果測試

測試序列為:

10010000111101000011100000011
00001110110101000110111100011
10101111010001001010111100010

參考文獻

m序列與BM演算法(密碼學)

python-----刪除列表中某個元素的3種方法

刪除列表中重複元素的幾種方法

Python獲取列表元素出現次數

[Python]正確複製列表的方法