Berlekamp-Massey演算法及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,⋯,aN−1) 是
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
其中
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=c1ak−1+c2ak−2+⋯+clak−l,k=l,l+1,⋯,N−1
則稱
<
f
(
x
)
,
l
>
\left< f\left( x \right) ,l \right>
給定一個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,⋯,aN−1),規定
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=0,n=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)xln,c0(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)an−1+⋯+cln(n)an−ln
(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+1,ln+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
m−lm≥n−ln,那麼取
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)−dndm−1x(m−lm)−(n−ln)fm(x)=fn(x)+x(m−lm)−(n−ln)fm(x)
<2>如果
m
−
l
m
<
n
−
l
n
m-l_m<n-l_n
m−lm<n−ln,那麼取
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(n−ln)−(m−lm)fn(x)−dndm−1fm(x)=x(n−ln)−(m−lm)fn(x)+fm(x)
3、不斷重複步驟2,直至
n
=
N
−
1
n=N-1
n=N−1,最後得到的
<
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 結果測試
測試序列為: