婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁(yè) > 知識(shí)庫(kù) > 二維碼的生成細(xì)節(jié)和原理

二維碼的生成細(xì)節(jié)和原理

熱門標(biāo)簽:揭陽(yáng)外呼系統(tǒng)公司 南召400電話辦理資費(fèi) 熱血傳奇沃瑪森林地圖標(biāo)注 地圖標(biāo)注植物名稱 鄭州中國(guó)移動(dòng)400電話申請(qǐng) 福建ai電銷機(jī)器人加盟公司 無(wú)錫電銷機(jī)器人銷售 招聘信息 去哪里辦卡 地圖標(biāo)注審核工作怎么樣注冊(cè)

二維碼又稱QR Code,QR全稱Quick Response,是一個(gè)近幾年來(lái)移動(dòng)設(shè)備上超流行的一種編碼方式,它比傳統(tǒng)的Bar Code條形碼能存更多的信息,也能表示更多的數(shù)據(jù)類型:比如:字符,數(shù)字,日文,中文等等。這兩天學(xué)習(xí)了一下二維碼圖片生成的相關(guān)細(xì)節(jié),覺(jué)得這個(gè)玩意就是一個(gè)密碼算法,在此寫一這篇文章 ,揭露一下。供好學(xué)的人一同學(xué)習(xí)之。

關(guān)于QR Code Specification,可參看這個(gè)PDF:http://raidenii.net/files/datasheets/misc/qr_code.pdf

基礎(chǔ)知識(shí)

首先,我們先說(shuō)一下二維碼一共有40個(gè)尺寸。官方叫版本Version。Version 1是21 x 21的矩陣,Version 2是 25 x 25的矩陣,Version 3是29的尺寸,每增加一個(gè)version,就會(huì)增加4的尺寸,公式是:(V-1)*4 + 21(V是版本號(hào)) 最高Version 40,(40-1)*4+21 = 177,所以最高是177 x 177 的正方形。

下面我們看看一個(gè)二維碼的樣例:

定位圖案

Position Detection Pattern是定位圖案,用于標(biāo)記二維碼的矩形大小。這三個(gè)定位圖案有白邊叫Separators for Postion Detection Patterns。之所以三個(gè)而不是四個(gè)意思就是三個(gè)就可以標(biāo)識(shí)一個(gè)矩形了。

Timing Patterns也是用于定位的。原因是二維碼有40種尺寸,尺寸過(guò)大了后需要有根標(biāo)準(zhǔn)線,不然掃描的時(shí)候可能會(huì)掃歪了。

Alignment Patterns 只有Version 2以上(包括Version2)的二維碼需要這個(gè)東東,同樣是為了定位用的。

功能性數(shù)據(jù)

Format Information 存在于所有的尺寸中,用于存放一些格式化數(shù)據(jù)的。

Version Information 在 >= Version 7以上,需要預(yù)留兩塊3 x 6的區(qū)域存放一些版本信息。

數(shù)據(jù)碼和糾錯(cuò)碼

除了上述的那些地方,剩下的地方存放 Data Code 數(shù)據(jù)碼 和 Error Correction Code 糾錯(cuò)碼。

數(shù)據(jù)編碼

我們先來(lái)說(shuō)說(shuō)數(shù)據(jù)編碼。QR碼支持如下的編碼:

Numeric mode 數(shù)字編碼,從0到9。如果需要編碼的數(shù)字的個(gè)數(shù)不是3的倍數(shù),那么,最后剩下的1或2位數(shù)會(huì)被轉(zhuǎn)成4或7bits,則其它的每3位數(shù)字會(huì)被編成 10,12,14bits,編成多長(zhǎng)還要看二維碼的尺寸(下面有一個(gè)表Table 3說(shuō)明了這點(diǎn))

Alphanumeric mode 字符編碼。包括 0-9,大寫的A到Z(沒(méi)有小寫),以及符號(hào)$ % * + – . / : 包括空格。這些字符會(huì)映射成一個(gè)字符索引表。如下所示:(其中的SP是空格,Char是字符,Value是其索引值) 編碼的過(guò)程是把字符兩兩分組,然后轉(zhuǎn)成下表的45進(jìn)制,然后轉(zhuǎn)成11bits的二進(jìn)制,如果最后有一個(gè)落單的,那就轉(zhuǎn)成6bits的二進(jìn)制。而編碼模式和字符的個(gè)數(shù)需要根據(jù)不同的Version尺寸編成9, 11或13個(gè)二進(jìn)制(如下表中Table 3)

 

 Byte mode, 字節(jié)編碼,可以是0-255的ISO-8859-1字符。有些二維碼的掃描器可以自動(dòng)檢測(cè)是否是UTF-8的編碼。

Kanji mode 這是日文編碼,也是雙字節(jié)編碼。同樣,也可以用于中文編碼。日文和漢字的編碼會(huì)減去一個(gè)值。如:在0X8140 to 0X9FFC中的字符會(huì)減去8140,在0XE040到0XEBBF中的字符要減去0XC140,然后把結(jié)果前兩個(gè)16進(jìn)制位拿出來(lái)乘以0XC0,然后再加上后兩個(gè)16進(jìn)制位,最后轉(zhuǎn)成13bit的編碼。

如下圖示例:

Extended Channel Interpretation (ECI) mode 主要用于特殊的字符集。并不是所有的掃描器都支持這種編碼。

Structured Append mode 用于混合編碼,也就是說(shuō),這個(gè)二維碼中包含了多種編碼格式。

FNC1 mode 這種編碼方式主要是給一些特殊的工業(yè)或行業(yè)用的。比如GS1條形碼之類的。

簡(jiǎn)單起見(jiàn),后面三種不會(huì)在本文 中討論。

下面兩張表中,

Table 2 是各個(gè)編碼格式的“編號(hào)”,這個(gè)東西要寫在Format Information中。注:中文是1101

Table 3 表示了,不同版本(尺寸)的二維碼,對(duì)于,數(shù)字,字符,字節(jié)和Kanji模式下,對(duì)于單個(gè)編碼的2進(jìn)制的位數(shù)。(在二維碼的規(guī)格說(shuō)明書中,有各種各樣的編碼規(guī)范表,后面還會(huì)提到)

 

 下面我們看幾個(gè)示例,

 示例一:數(shù)字編碼

 在Version 1的尺寸下,糾錯(cuò)級(jí)別為H的情況下,編碼: 01234567

1. 把上述數(shù)字分成三組: 012 345 67

2. 把他們轉(zhuǎn)成二進(jìn)制:  012 轉(zhuǎn)成 0000001100;  345 轉(zhuǎn)成 0101011001;  67 轉(zhuǎn)成 1000011。

3. 把這三個(gè)二進(jìn)制串起來(lái): 0000001100 0101011001 1000011

4. 把數(shù)字的個(gè)數(shù)轉(zhuǎn)成二進(jìn)制 (version 1-H是10 bits ): 8個(gè)數(shù)字的二進(jìn)制是 0000001000

5. 把數(shù)字編碼的標(biāo)志0001和第4步的編碼加到前面:  0001 0000001000 0000001100 0101011001 1000011

 示例二:字符編碼

 在Version 1的尺寸下,糾錯(cuò)級(jí)別為H的情況下,編碼: AC-42

1. 從字符索引表中找到 AC-42 這五個(gè)字條的索引 (10,12,41,4,2)

2. 兩兩分組: (10,12) (41,4) (2)

3.把每一組轉(zhuǎn)成11bits的二進(jìn)制:

(10,12) 10*45+12 等于 462 轉(zhuǎn)成 00111001110
(41,4) 41*45+4 等于 1849 轉(zhuǎn)成 11100111001
(2) 等于 2 轉(zhuǎn)成 000010

4. 把這些二進(jìn)制連接起來(lái):00111001110 11100111001 000010

5. 把字符的個(gè)數(shù)轉(zhuǎn)成二進(jìn)制 (Version 1-H為9 bits ): 5個(gè)字符,5轉(zhuǎn)成 000000101

6. 在頭上加上編碼標(biāo)識(shí) 0010 和第5步的個(gè)數(shù)編碼:  0010 000000101 00111001110 11100111001 000010

 結(jié)束符和補(bǔ)齊符

假如我們有個(gè)HELLO WORLD的字符串要編碼,根據(jù)上面的示例二,我們可以得到下面的編碼,

編碼 字符  HELLO WORLD編碼
0010 000001011 01100001011 01111000110 10001011100 10110111000 10011010100 001101

 我們還要加上結(jié)束符:

編碼 字符數(shù) HELLO WORLD編碼 結(jié)束
0010 000001011 01100001011 01111000110 10001011100 10110111000 10011010100 001101 0000

按8bits重排

 如果所有的編碼加起來(lái)不是8個(gè)倍數(shù)我們還要在后面加上足夠的0,比如上面一共有78個(gè)bits,所以,我們還要加上2個(gè)0,然后按8個(gè)bits分好組:

 00100000   01011011   00001011   01111000   11010001   01110010   11011100   01001101   01000011   01000000

 補(bǔ)齊碼(Padding Bytes)

 最后,如果如果還沒(méi)有達(dá)到我們最大的bits數(shù)的限制,我們還要加一些補(bǔ)齊碼(Padding Bytes),Padding Bytes就是重復(fù)下面的兩個(gè)bytes:11101100 00010001 (這兩個(gè)二進(jìn)制轉(zhuǎn)成十進(jìn)制是236和17,我也不知道為什么,只知道Spec上是這么寫的)關(guān)于每一個(gè)Version的每一種糾錯(cuò)級(jí)別的最大Bits限制,可以參看QR Code Spec的第28頁(yè)到32頁(yè)的Table-7一表。

 假設(shè)我們需要編碼的是Version 1的Q糾錯(cuò)級(jí),那么,其最大需要104個(gè)bits,而我們上面只有80個(gè)bits,所以,還需要補(bǔ)24個(gè)bits,也就是需要3個(gè)Padding Bytes,我們就添加三個(gè),于是得到下面的編碼:

 00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 01000000 11101100 00010001 11101100

上面的編碼就是數(shù)據(jù)碼了,叫Data Codewords,每一個(gè)8bits叫一個(gè)codeword,我們還要對(duì)這些數(shù)據(jù)碼加上糾錯(cuò)信息。

糾錯(cuò)碼

上面我們說(shuō)到了一些糾錯(cuò)級(jí)別,Error Correction Code Level,二維碼中有四種級(jí)別的糾錯(cuò),這就是為什么二維碼有殘缺還能掃出來(lái),也就是為什么有人在二維碼的中心位置加入圖標(biāo)。

錯(cuò)誤修正容量
L水平 7%的字碼可被修正
M水平 15%的字碼可被修正
Q水平 25%的字碼可被修正
H水平 30%的字碼可被修正

那么,QR是怎么對(duì)數(shù)據(jù)碼加上糾錯(cuò)碼的?首先,我們需要對(duì)數(shù)據(jù)碼進(jìn)行分組,也就是分成不同的Block,然后對(duì)各個(gè)Block進(jìn)行糾錯(cuò)編碼,對(duì)于如何分組,我們可以查看QR Code Spec的第33頁(yè)到44頁(yè)的Table-13到Table-22的定義表。注意最后兩列:

Number of Error Code Correction Blocks :需要分多少個(gè)塊。
Error Correction Code Per Blocks:每一個(gè)塊中的code個(gè)數(shù),所謂的code的個(gè)數(shù),也就是有多少個(gè)8bits的字節(jié)。

舉個(gè)例子:上述的Version 5 + Q糾錯(cuò)級(jí):需要4個(gè)Blocks(2個(gè)Blocks為一組,共兩組),頭一組的兩個(gè)Blocks中各15個(gè)bits數(shù)據(jù) + 各 9個(gè)bits的糾錯(cuò)碼(注:表中的codewords就是一個(gè)8bits的byte)(再注:最后一例中的(c, k, r )的公式為:c = k + 2 * r,因?yàn)楹竽_注解釋了:糾錯(cuò)碼的容量小于糾錯(cuò)碼的一半)

下圖給一個(gè)5-Q的示例(因?yàn)槎M(jìn)制寫起來(lái)會(huì)讓表格太大,所以,我都用了十進(jìn)制,我們可以看到每一塊的糾錯(cuò)碼有18個(gè)codewords,也就是18個(gè)8bits的二進(jìn)制數(shù))

數(shù)據(jù) 對(duì)每個(gè)塊的糾錯(cuò)碼
1 1 67 85 70 134 87 38 85 194 119 50 6 18 6 103 38 

213 199 11 45 115 247 241 223 229 248 154

 117 154 111 86 161 111 39

2 246 246 66 7 118 134 242 7 38 86 22 198 199 146 6 

87 204 96 60 202 182 124 157 200 134 27 

129 209 17 163 163 120 133

2 1 182 230 247 119 50 7 118 134 87 38 82 6 134 151 50 7

148 116 177 212 76 133 75 242 238 76 195

 230 189 10 108 240 192 141

2 70 247 118 86 194 6 151 50 16 236 17 236 17 236 17 236

235 159 5 173 24 147 59 33 106 40 255 

172 82 2 131 32 178 236

 注:二維碼的糾錯(cuò)碼主要是通過(guò)Reed-Solomon error correction(里德-所羅門糾錯(cuò)算法)來(lái)實(shí)現(xiàn)的。對(duì)于這個(gè)算法,對(duì)于我來(lái)說(shuō)是相當(dāng)?shù)膹?fù)雜,里面有很多的數(shù)學(xué)計(jì)算,比如:多項(xiàng)式除法,把1-255的數(shù)映射成2的n次方(0=n=255)的伽羅瓦域Galois Field之類的神一樣的東西,以及基于這些基礎(chǔ)的糾錯(cuò)數(shù)學(xué)公式,因?yàn)槲业臄?shù)據(jù)基礎(chǔ)差,對(duì)于我來(lái)說(shuō)太過(guò)復(fù)雜,所以我一時(shí)半會(huì)兒還有點(diǎn)沒(méi)搞明白,還在學(xué)習(xí)中,所以,我在這里就不展開(kāi)說(shuō)這些東西了。還請(qǐng)大家見(jiàn)諒了。(當(dāng)然,如果有朋友很明白,也繁請(qǐng)教教我)

 最終編碼

 穿插放置

 如果你以為我們可以開(kāi)始畫圖,你就錯(cuò)了。二維碼的混亂技術(shù)還沒(méi)有玩完,它還要把數(shù)據(jù)碼和糾錯(cuò)碼的各個(gè)codewords交替放在一起。如何交替呢,規(guī)則如下:

 對(duì)于數(shù)據(jù)碼:把每個(gè)塊的第一個(gè)codewords先拿出來(lái)按順度排列好,然后再取第一塊的第二個(gè),如此類推。如:上述示例中的Data Codewords如下:

塊1 67 85 70 134 87 38 85 194 119 50 6 18 6 103 38
塊2 246 246 66 7 118 134 242 7 38 86 22 198 199 146 6
塊3 182 230 247 119 50 7 118 134 87 38 82 6 134 151 50 7
塊4 70 247 118 86 194 6 151 50 16 236 17 236 17 236 17 236

 我們先取第一列的:67, 246, 182, 70

然后再取第二列的:67, 246, 182, 70, 85,246,230 ,247

如此類推:67, 246, 182, 70, 85,246,230 ,247 ………  ……… ,38,6,50,17,7,236

 對(duì)于糾錯(cuò)碼,也是一樣:

塊1 213 199 11 45 115 247 241 223 229 248 154 117 154 111 86 168 111 39
塊2 87 204 96 60 202 182 124 157 200 134 27 129 209 17 163 163 120 133
塊3 148 116 177 212 76 133 75 242 238 76 195 230 189 10 108 240 192 141
塊4 235 159 5 173 24 147 59 33 106 40 255 172 82 2 131 32 178 236

 和數(shù)據(jù)碼取的一樣,得到:213,87,148,235,199,204,116,159,…… …… 39,133,141,236

然后,再把這兩組放在一起(糾錯(cuò)碼放在數(shù)據(jù)碼之后)得到:

 67, 246, 182, 70, 85, 246, 230, 247, 70, 66, 247, 118, 134, 7, 119, 86, 87, 118, 50, 194, 38, 134, 7, 6, 85, 242, 118, 151, 194, 7, 134, 50, 119, 38, 87, 16, 50, 86, 38, 236, 6, 22, 82, 17, 18, 198, 6, 236, 6, 199, 134, 17, 103, 146, 151, 236, 38, 6, 50, 17, 7, 236, 213, 87, 148, 235, 199, 204, 116, 159, 11, 96, 177, 5, 45, 60, 212, 173, 115, 202, 76, 24, 247, 182, 133, 147, 241, 124, 75, 59, 223, 157, 242, 33, 229, 200, 238, 106, 248, 134, 76, 40, 154, 27, 195, 255, 117, 129, 230, 172, 154, 209, 189, 82, 111, 17, 10, 2, 86, 163, 108, 131, 161, 163, 240, 32, 111, 120, 192, 178, 39, 133, 141, 236

這就是我們的數(shù)據(jù)區(qū)。

 Remainder Bits

最后再加上Reminder Bits,對(duì)于某些Version的QR,上面的還不夠長(zhǎng)度,還要加上Remainder Bits,比如:上述的5Q版的二維碼,還要加上7個(gè)bits,Remainder Bits加零就好了。關(guān)于哪些Version需要多少個(gè)Remainder bit,可以參看QR Code Spec的第15頁(yè)的Table-1的定義表。

畫二維碼圖

Position Detection Pattern

首先,先把Position Detection圖案畫在三個(gè)角上。(無(wú)論Version如何,這個(gè)圖案的尺寸就是這么大)

Alignment Pattern

然后,再把Alignment圖案畫上(無(wú)論Version如何,這個(gè)圖案的尺寸就是這么大)

 

關(guān)于Alignment的位置,可以查看QR Code Spec的第81頁(yè)的Table-E.1的定義表(下表是不完全表格)

下圖是根據(jù)上述表格中的Version8的一個(gè)例子(6,24,42)

Timing Pattern

接下來(lái)是Timing Pattern的線(這個(gè)不用多說(shuō)了)

Format Information

再接下來(lái)是Formation Information,下圖中的藍(lán)色部分。

Format Information是一個(gè)15個(gè)bits的信息,每一個(gè)bit的位置如下圖所示:(注意圖中的Dark Module,那是永遠(yuǎn)出現(xiàn)的)

這15個(gè)bits中包括:

5個(gè)數(shù)據(jù)bits:其中,2個(gè)bits用于表示使用什么樣的Error Correction Level, 3個(gè)bits表示使用什么樣的Mask
10個(gè)糾錯(cuò)bits。主要通過(guò)BCH Code來(lái)計(jì)算
然后15個(gè)bits還要與101010000010010做XOR操作。這樣就保證不會(huì)因?yàn)槲覀冞x用了00的糾錯(cuò)級(jí)別和000的Mask,從而造成全部為白色,這會(huì)增加我們的掃描器的圖像識(shí)別的困難。

下面是一個(gè)示例:

 

 關(guān)于Error Correction Level如下表所示:

關(guān)于Mask圖案如后面的Table 23所示。

Version Information

再接下來(lái)是Version Information(版本7以后需要這個(gè)編碼),下圖中的藍(lán)色部分。

Version Information一共是18個(gè)bits,其中包括6個(gè)bits的版本號(hào)以及12個(gè)bits的糾錯(cuò)碼,下面是一個(gè)示例:

 

 而其填充位置如下:

 

 數(shù)據(jù)和數(shù)據(jù)糾錯(cuò)碼

然后是填接我們的最終編碼,最終編碼的填充方式如下:從左下角開(kāi)始沿著紅線填我們的各個(gè)bits,1是黑色,0是白色。如果遇到了上面的非數(shù)據(jù)區(qū),則繞開(kāi)或跳過(guò)。

掩碼圖案

這樣下來(lái),我們的圖就填好了,但是,也許那些點(diǎn)并不均衡,如果出現(xiàn)大面積的空白或黑塊,會(huì)告訴我們掃描識(shí)別的困難。所以,我們還要做Masking操作(靠,還嫌不復(fù)雜)QR的Spec中說(shuō)了,QR有8個(gè)Mask你可以使用,如下所示:其中,各個(gè)mask的公式在各個(gè)圖下面。所謂mask,說(shuō)白了,就是和上面生成的圖做XOR操作。Mask只會(huì)和數(shù)據(jù)區(qū)進(jìn)行XOR,不會(huì)影響功能區(qū)。(注:選擇一個(gè)合適的Mask也是有算法的)

 

 其Mask的標(biāo)識(shí)碼如下所示:(其中的i,j分別對(duì)應(yīng)于上圖的x,y)

下面是Mask后的一些樣子,我們可以看到被某些Mask XOR了的數(shù)據(jù)變得比較零散了。

Mask過(guò)后的二維碼就成最終的圖了。

好了,大家可以去嘗試去寫一下QR的編碼程序,當(dāng)然,你可以用網(wǎng)上找個(gè)Reed Soloman的糾錯(cuò)算法的庫(kù),或是看看別人的源代碼是怎么實(shí)現(xiàn)這個(gè)繁鎖的編碼。

(全文完)

您可能感興趣的文章:
  • 利用java實(shí)現(xiàn)二維碼和背景圖的合并
  • java生成彩色附logo二維碼
  • php微信開(kāi)發(fā)之帶參數(shù)二維碼的使用
  • Android實(shí)現(xiàn)二維碼掃描和生成的簡(jiǎn)單方法
  • PHP識(shí)別二維碼的方法(php-zbarcode安裝與使用)
  • php微信開(kāi)發(fā)之批量生成帶參數(shù)的二維碼
  • 微信QQ的二維碼登錄原理js代碼解析
  • Android仿微信二維碼和條形碼
  • 用JAVA 設(shè)計(jì)生成二維碼詳細(xì)教程

標(biāo)簽:東莞 南昌 鹽城 桂林 景德鎮(zhèn) 宣城 文山 黔南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《二維碼的生成細(xì)節(jié)和原理》,本文關(guān)鍵詞  二維,碼,的,生成,細(xì)節(jié),和,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《二維碼的生成細(xì)節(jié)和原理》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于二維碼的生成細(xì)節(jié)和原理的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 英德市| 丹巴县| 曲沃县| 交口县| 恩施市| 万盛区| 自贡市| 桂平市| 无棣县| 开江县| 乌兰察布市| 泊头市| 当涂县| 乌兰浩特市| 普格县| 治多县| 靖远县| 保德县| 福州市| 绥芬河市| 辽宁省| 巩留县| 光山县| 萝北县| 饶阳县| 鄄城县| 嫩江县| 吴旗县| 安徽省| 洮南市| 会东县| 罗山县| 商水县| 玉门市| 台安县| 嘉义市| 奉新县| 芜湖市| 西丰县| 旅游| 会宁县|