【python】Reed-solomon codes的二维码应用(七)

        今天说回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的译码,明日更。

             

                    


猜你喜欢

转载自blog.csdn.net/weixin_39878297/article/details/80172972