二进制矩阵乘法_QR Code快速响应矩阵 二维码编码原理全过程详解(一)

dad60c0998906dfc9ffbf96fa7ddbac9.png

方法概述:

1.数据分析:

分析所需要编码的数据流,确定需要编码的字符类型,以选定相应的模式来高效的将数据转变为二进制位流;

根据输入数据多少选择相应的版本和纠错等级。

2.数据编码:

根据所采用的模式的相关规则将数据转为位流,需要模式转换时,可以在新模式段开始前加入模式指示符以进行模式转换;最后将所得的位流每8位分作一个码字,再按需要加入终止符和补齐码。

3.纠错编码:

按版本和纠错等级的需求将数据码字序列分块,按块生成纠错码字。

4.构造最终信息:

将每一块的数据码字和纠错码字装配为最终序列,必要时加剩余位。

5.布置矩阵:

将寻像图形,分隔符,定位图形,校正图形和码字序列放入矩阵。

6.掩码:

在8种掩码中挑选最适合(惩罚值最小的)的掩码。

7.格式和版本信息:

格式信息包括纠错等级和掩码模式共5个二进制位再加10个格式纠错二进制位;

版本信息在Version7以上的版本需要添加。

实例:

编码内容:祝祖国母亲生日快乐❤

——祖国母亲的小儿砸LXW

编码的数据里,主要是汉字以及汉字符,另外还有一个难一点的Emoji表情符,和一个换行符,还有三个字母是笔者名字缩写。

1.数据分析:

对数据分析可知,数据字符种类多,有中文,那么,数字模式、字母数字模式、8位字节模式是显然不行了,我们采用ECI这个模式;另外版本和纠错等级我们可先将数据编好码再选。

2.数据编码:

我们选取的模式为ECI模式,首先,如果不是缺省的ECI,格式为:

标头+一个或多个模式段

标头:ECI模式指示符,即0111,还要ECI指定符8位,通俗的来讲,我们要什么码来编,就用ECI下对应的编号,比如我们现在要用UTF-8来编码我们的数据,看到下图中,UTF-8的ECI Id为26,化作8为二进制就是0001 1010;

a64c9dfb753ee6e4dea228854b33d56b.png

然后我们就把标头编好了,为:0111 0001 1010

接下来是模式段,我们采用8位字节模式,模式指示符为0100;注意:这个模式指示符不是和开头的ECI模式那里选模式一样,这里的模式不能决定编码方式,它和紧随其后的字符计数指示符对应,可以算出数据码区的长度。

字符计数指示符的位数随版本和模式而不同,其对应表格如下:

c494582a1fe65c46789cf471c67316a4.png

所以我们的字符计数指示符的位数为8位,由于笔者我已经提前将数据编码好了,我可以将此处编为0100 0100,即十进制的68,表示后面还有68个8位字节(此处与模式相对应)。截至现在,我们的到的码字已经有:

0111 0001 1010 0100 0100 0100;

我们再来编码内容,第一个字为:祝。

由于我们是采用UTF-8编码的,所以我们需要得到“祝“字的UTF-8码,希望用C/C++实现二维码的,在码值获得可能不太方便,但使用Java的话,就方便多了。

下面我觉得有必要讲一下UTF-8与unicode的联系,

UTF-8其实是建立在unicode的基础之上的,但是unicode对于编号小的数据很不友好,比如1号码,000001(hex)就是它的unicode码值,也就相当于24位二进制位。所以提出了UTF-8,UTF-16,UTF-32等编码方式,UTF-8是使用最多的一种,它和unicode的转换为:

c8403849f33ef8bec4aa507ea0229513.png

(温馨提示,unicode码值可以在word中使用快捷键alt+X得到)

比如,我们的“祝“字的unicode码值为795D(hex),二进制也就是:

0111 1001 0101 1101,那么转换为UTF-8码为:1110 0111 1010 0101 1001 1101;

好,那么我们对“祝“字的编码即为

1110 0111

1010 0101

1001 1101;

再编“祖“:同理得:

1110 0111

1010 0101

1001 0110;

“国“:

1110 0101

1001 1011

1011 1101

其余汉字省略,

然后我们来到❤处,这是特定应用格式化信息得符号,

https://dict.emojiall.com/zh-hans/emoji

9aa3e571665c35407d3b28e9861c72df.png

大家可以在这个网址查到它的unicode码,它的unicode码有8位为:2764FE0F(hex),也就是相当于两个汉字。

结合为:

1110 0010

1001 1101

1010 0100

1110 1111

1011 1000

1000 1111

然后再编码下一个字符为回车符,其UTF-8码值等于ASCII码值为13,即

0000 1101

还要有一个换行符,这个换行符是自己手动输入的,上个回车是作者输入❤时自带的;

其UTF-8码也等于其ASCII码值10,即

0000 1010

在然后是“——”这两个符号,这两个符号的unicode码为2014(hex);

即为:

1110 0010

1000 0000

1001 0100

1110 0010

1000 0000

1001 0100

然后又是汉字,我们跳过,来到“L”处,

L的unicode码值为004C(hex),则他的UTF-8编码为:

0100 1100

X为:

0101 1000

W为:

0101 0111

到此,我们算是将数据编完了。

我们现在来选版本和纠错等级:

我们看到下图,每个版本和纠错等级后面的括号中,c表示每块中的纠错码字,k表示总的数据码字,r表示纠错容量;

a44d0e15c3c203074406ede125b7bc7c.png

我们现在不妨选择版本Version4,纠错L,那么我们可以知道,其数据码字数为80,即80*8个二进制位,而目前我们编好的码为70*8个二进制位,因此,我们的终止符应该为

0000 0000,注意终止符在容量不够的时候可以缩短或者省略;现在我们的码字数为72,而我们选的版本和纠错等级对应得数据码字数是80,那么应该添加若干个此序列

1110 1100

0001 0001

直至添满,那么我们应填充

1110 1100

0001 0001

1110 1100

0001 0001

1110 1100

0001 0001

1110 1100

0001 0001

好的,一直到现在,我们已经将数据码字全部编写好了,接下来就是纠错码了。

纠错码字是用数据码字多项式除以生成多项式得到,这著名的Reed-Solomon算法比较复杂,我们要理解清楚galois有限域中的加法和乘法是怎么运算的,这些东西,我看过一些文章,他们都讲的模模糊糊,然后就带过了,因此我打算下一篇文章来讲纠错编码的原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值