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

    ( 注:本部分博客主要结合周老师的PPT以及查找的资料,尝试去解释Reed-Solomon Codes的数学原理和信息论原理,并讨论Reed-Solomon Codes在QR二维码方面的应用。)

        其实上文中出现的乘法并不是最方便的,因为要经过多次循环,所以出现了基于对数的乘法,使用伽罗华域巧妙地将乘法变成加法。

        我们知道,对于模2来说乘法是非常容易的,只要向左移一位(类似于乘2,就是本身的幂加一),再与100011101(比8bits还多一位的素多项式,类似于素数)进行异或,异或的结果就是对应的多项式的系数,例如:

α^0 = 00000001 α^4 = 00010000 α^8 = 00011101 α^12 = 11001101
       α^1 = 00000010 α^5 = 00100000 α^9 = 00111010 α^13 = 10000111
       α^2 = 00000100 α^6 = 01000000 α^10 = 01110100 α^14 = 00010011
       α^3 = 00001000 α^7 = 10000000 α^11 = 11101000 α^15 = 00100110
       (注释: α^7 * α超过了8-bit,需要与100011101异或得到α^8,依此类推。)
在这里要解释一下,为什么要与100011101异或?

      100011101= 1*x^8+0*x^7+0*x^6+0*x^5+1*x^4+1*x^3+1*x^2+0*x^1+1*x^0,前面我们说过mod(p)可将得出来的结果控制在[0,p-1]内,所以当我们将a^k mod (100011101) = 100011101 - a^k,多项式的四则运算里减法和加法都是异或。

        于是我们以此类推,直到a^255 = 0000 0001 结束,我们能够将所有[1,255]中的数表示成伽罗华域的符号,从中可以发现另外一种乘法,比如a^34 * a^8 = a^(34+8) = a^42,接下来我们将a^42转换就可以得到乘积了。

        那么我们如何将生成子的幂变成多项式呢,事实上是有表可查的,也可以用Python来生成列表:

table = [0]*512   
m_table = [0]*256  
def tables(prim = 0x11B):  
    x = 1;     //g^0  
    for i in range(0,255):    
        table[i] = x
        m_table[x] = i
        x<<1      
        if x & 0x100 :    #最高指数已经到了8,需要异或上prim 
            x ^= prim     #用到了前面说到的乘法技巧  
   

         对于逆元表,我们也可以用Python描述。若a和b互为逆元,则有a*b = e。用生成元表示为:a^n* a^m = e = 1。又因为e = a^0 = a^255,所以g^k * g(255-k) = g^(k + 255 -k) = e。于是g^k 和 g^(255-k)互为逆元。对于多项式值val,求其逆元。可以先求val对应的g幂次是多少。即g的多少次方等于val。可以通过反向表查询, 设为k。那么其逆元的幂次为255-k。此时再通过正向表查询即可。实现代码如下:

        

inverse_table = [0]*256
def inverseTable(table, m_table):  
    for i in range(1,255):   #0没有逆元,所以从1开始  
        k = m_table[i];  
        k = 255 - k;  
        inverse_table[i] = table[k]

接下来我们直接可以求乘法啦,炒鸡简单的是不是!

def table_mul(x,y):
    if x==0 or y==0:
        return 0
    return table[m_table[x] + m_table[y]]
       好滴明天终于可以更除法了~

猜你喜欢

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