今天说回RS码,使用之前的知识可以重新让我们猜测下图矩阵图具体的内容:
RS码的生成多项式可以从x^q^m - 1 = f1(x) *f2(x) *f3(x) *f4(x) ......fk(x) 中的素多项式中分解出来:
g(x) = LMC ( f1(x),f2(x),f3(x),f4(x) ......fk(x) )
所以我们利用这个方法将g(x)得到之后,又因为g(x) = (x - α^0) (x - α^1) (x - α^2) (x - α^3)......(x - α^(m-1)),我们将需要存储的数据msg_in用综合除法除以g(x),最后的商+余数的列表即为RS的编码。
代码方法如下:
def rs_generator_poly(nsym): #用数量为m个的校验码组成生成多项式 g = [1] for i in range(0,nsym): # g = gf_poly_mul(g, [1, gf_pow(2, i)]) # 指数运算,跟下面等效 g = gf_poly_mul(g, [1, gf_exp[i]]) return g def gf_poly_div(dividend, divisor): #综合除法 '''适用于GF(2^p)域的快速多项式除法.''' # 注意: 多项式系数需要按幂次由高到低排序. 例如: 1 + 2x + 5x^2 = [5, 2, 1], 而非 [1, 2, 5] msg_out = list(dividend) # 复制被除数(尾部后缀ecc字节, 用0填充) #normalizer = divisor[0] # precomputing for performance for i in range(0, len(dividend) - (len(divisor)-1)): #msg_out[i] /= normalizer coef = msg_out[i] if coef != 0: # 避免log(0)未定义错误. for j in range(1, len(divisor)): # 因为多项式的首位都是1, (1^1==0)所以可以跳过 if divisor[j] != 0: # log(0) is undefined msg_out[i + j] ^= gf_mul(divisor[j], coef) # 等价于数学表达式:msg_out[i + j] += -divisor[j] * coef ,但异或运高效 # msg_out 包含商和余数, 余数的最高幂次( == length-1)和除数一样, 下面计算分断点. separator = -(len(divisor)-1) return msg_out[:separator], msg_out[separator:] # 返回商, 余数. def rs_encode_msg(msg_in, nsym): #RS码的编码过程 '''Reed-Solomon main encoding function''' gen = rs_generator_poly(nsym) # 后缀ecc字节位用0填充, 之后用生成子(irreducible generator polynomial)除 _, remainder = gf_poly_div(msg_in + [0] * (len(gen)-1), gen) # 余数就是 RS 码! 后缀到原信息之后形成全部编码 msg_out = msg_in + remainder # Return the codeword return msg_out
在这里解释一下msg_out的内容,我们设msg_in_new = msg_in + [0] * (len(gen)-1),将msg_in_new 除以g(x) = (x - α^0) (x - α^1) (x - α^2) (x - α^3)......(x - α^(m-1)),设综合除法过程中,遍历0~m-1的本原,即每除以(x - α^k) 的商为Qk,余数为Rk,最后的msg_out为列表[Qm,Rm-1,Rm-2,.......R2,R1,R0],其中Qm也是一个商的数字列表,msg_out的关系满足:
( Qm ^ Rm-1 ) * (x - α^(m-1)) = Qm -1 (这里的^指的是异或)
( Qm-1 ^ Rm-2 ) * (x - α^(m-2)) = Qm-2
( Qm-2 ^ Rm-3 ) * (x - α^(m-3)) = Qm-3
........
( Q2 ^ R1 ) * (x - α^1) = Q1
( Q1 ^ R0 ) * (x - α^0) = msg_in_new
其中最后我们能够得到RS的编码,编码其实比较简单,只需用上多项式除法就行了,难的是RS的译码,明日更。