【笔记】二维码中的 Reed-Solomon 编码

本文详细介绍了如何实现二维码中的Reed-Solomon编码,包括模二除法、模二乘法、多项式运算及数据恢复等步骤。通过JavaScript实现,展示了在伽罗瓦域中进行的编码和解码过程,以确保数据的准确性。
摘要由CSDN通过智能技术生成

如题。。因为看了某针的二维码视频,所以想试试实现自己写个,于是就有了这篇文章。
这里主要研究的是二维码的纠错码。使用语言为Javascript,所有代码均可在浏览器直接运行。

模二除法

因为二维码的编码是在伽罗瓦域中进行的,所以需要大量用到异或和模二乘法。异或很简单,但模二乘法就很复杂了,这里先实现下模二乘法的第二部取余。
模二除法的算法原理参考于模2除法(CRC校验码计算)

      1 0 1 1     //商
---------------
1 1 1 1 0 0 0     //被除数,注意首位为1
1 1 0 1	          //被除数首位为1,除以除数
---------------
  0 1 0 0 0 0     //余数去除首位,作为新的被除数
  0 0 0 0         //被除数首位为0,除以0
---------------
    1 0 0 0 0     //余数去除首位,作为新的被除数
    1 1 0 1       //被除数首位为1,除以除数  
---------------
      1 0 1 0     //余数去除首位,作为新的被除数
      1 1 0 1     //被除数首位为1,除以除数
---------------
        1 1 1     //余数,此时余数位数少于除数,不能继续除了

看计算过程可以得知,模二除法就是看除的时候某一位是不是1,如果是1就用被除数和除数异或,商1,然后看下一位。
我写的算法和上述有些不同,我是看在某一位的时候用被除数和除数做异或运算后被除数是否变小,如果变小则商一。这个算法其实和最简单的竖列除法差不多,都是尽可能的让被除数变小,待会的多项式除法我会用这个思路。光说可能没那么容易理解,上代码:

function mod_div(a,b){
   
    ori = b;
    while(a > b){
   
        b <<= 1;
    }

    let ans = 0;
    while(b >= ori){
   
        ans <<= 1;
        if((a ^ b) < a){
   
            a ^= b;
            ans += 1;
        }
        b >>= 1;
    }

    return a;
}

在算法中,结果的商也被求出来了,在while结束时的ans即使商,不过由于我们只关心余数,这里就先不管它了。

模二乘法

接下来是模二乘法:

function xor_mul(a,b){
   
    let ans = 0;
    while(b > 0){
   
        if(b&1){
   
            ans ^= a;
        }
        b >>= 1;
        a <<= 1;
        //console.log(ans)
    }
    return ans;
}

算法和快速乘法差不多,这里就不多解释了。

伽罗瓦域中的模二乘法(?)

function mod_mul(a, b, p){
   
    return mod_div(xor_mul(a, b),p);
}

有了上面的算法,就可以表示出模二乘法了。其中的p是事先设定好的数值,在视频中这个数是0b1011,也就是11 。
接下来验证我们的算法,很简单,我们试着输出一张GF(2^3)的完整乘法表,然后和视频中对照一下就知道算法正确不正确了:

mod_div_2 = [];
var i = 0;
for(i=0;i<8;++i){
   
    mod_div_2[i] = [0,];
}

table = '';
for(i=0;i<8;i++){
   
    for(j=0;j<8;j++){
   
        tmp = mod_mul(i, j, 11);
        table += tmp;
        table += ' ';
        mod_div_2[tmp][i] = j;
    }
    table += '\n';
}
console.log('-----table-----');
console.log(table);
console.log('-----table2-----');
console.log(mod_div_2);

输出结果:

-----table-----
0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
0 2 4 6 3 1 7 5
0 3 6 5 7 4 1 2
0 4 3 7 6 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值