二維碼由來(lái)在1994年,這個(gè)類似于一個(gè)正方形馬賽克的圖片由日本DENSO WAVE公司發(fā)明----兩位程序員為了追蹤汽車零部件而設(shè)計(jì)。而現(xiàn)在,應(yīng)用更為廣泛的是由美國(guó)人設(shè)計(jì)的pdf417,datamatrx..其中的pdf417是由留美華人王寅敬博士發(fā)明。 其實(shí)很長(zhǎng)時(shí)間里二維碼應(yīng)用于產(chǎn)品追蹤,物品識(shí)別和庫(kù)存管理等工業(yè)用途。直到智能手機(jī)和微信在中國(guó)普及,二維碼才變成了一個(gè)可以被大眾隨時(shí)“掃一掃”的工具,或者說(shuō)人人手里都有了一個(gè)“二維碼掃描器”。二維碼在中國(guó)應(yīng)用的范圍比較廣,而在網(wǎng)上支付方面,二維碼也存在一定的風(fēng)險(xiǎn)。其實(shí),直接掃碼很危險(xiǎn)。有網(wǎng)友稱其在街頭張貼的廣告上掃描了一個(gè)二維碼之后, 手機(jī)剛充的100元話費(fèi)就不翼而飛。他掃描了一個(gè)貼在墻上的交友類二維碼后,并未下載安裝交友軟件,然后就被通知手機(jī)欠費(fèi)。結(jié)果檢測(cè)手機(jī)發(fā)現(xiàn),被安裝了手機(jī)病毒軟件,導(dǎo)致剛充的話費(fèi)被偷走。央行在2014年叫停二維碼支付后時(shí)隔兩年,于2016年8月3日官方才重新承認(rèn)二維碼的支付地位。 生成原理:該原理是, 為了利用計(jì)算機(jī)內(nèi)部邏輯,用數(shù)字“0”和數(shù)字“1”作為代碼,同時(shí)使用若干個(gè)與二進(jìn)制相對(duì)應(yīng)的幾何形體表示文字?jǐn)?shù)值信息。 這里面我有幾個(gè)小知識(shí)點(diǎn)想提一提。 知識(shí)點(diǎn)一:二維碼共有40個(gè)尺寸 也就是版本version,Version 1.0是21 x 21的正方形,Version 2.0是 25 x 25的(公式:(V-1)*4 + 21)。所以最大的尺寸就是177 x 177 的正方形。 知識(shí)點(diǎn)二:三個(gè)點(diǎn)確定一個(gè)面 二維碼只有三個(gè)角上有位置探測(cè)圖案,就是這個(gè)就是為了更好的讀取二維碼。那有人問(wèn)為什么不是四個(gè)能,這個(gè)角也不是多余的,可以鑲嵌別的信息。 知識(shí)點(diǎn)三:旋轉(zhuǎn)二維碼,也可以識(shí)別 因?yàn)橛兄R(shí)點(diǎn)二中所說(shuō)的位置探測(cè)圖案和分隔符,所以,無(wú)論是正著掃碼,還是豎著掃碼,或者斜著掃碼,信息都可以被識(shí)別。 再來(lái)看看,二維碼的工作原理:
因?yàn)槊總€(gè)碼制有自己的字符集,一個(gè)一個(gè)的字符占據(jù)自己的位置。所以,通過(guò)掃描能讀取的數(shù)據(jù)信息在二維碼中的位置是由定位圖形和分隔符決定的。才能夠快速地識(shí)別和處理圖形旋轉(zhuǎn)、變化等問(wèn)題。 二維碼可以在水平和豎直方向上進(jìn)行編碼,用正方形的黑白格來(lái)記錄信息,原理是利用了二進(jìn)制的0和1,打個(gè)比方,現(xiàn)在有一個(gè)10乘10格子的二維碼,每一行都有黑白格,如果用1表示白色的格子,0表示黑色的格子,那么我們可以用類似“0100101100”這樣的一行數(shù)字來(lái)表示每一行的代碼,那么將10個(gè)這樣的數(shù)字行排列起來(lái),就組成了一個(gè)二維碼,我們掃碼就相當(dāng)于解碼的過(guò)程,可以識(shí)別二維碼上的信息。 二維碼還具有容錯(cuò)性,一些二維碼只需要掃前面幾行就可以識(shí)別出信息,哪怕二維碼局部破損丟失都可能識(shí)別信息,不需要掃全,它比普通條形碼譯碼錯(cuò)誤率50萬(wàn)分之1還要低,誤碼率低于1000萬(wàn)分之1。 數(shù)據(jù)編碼 我們先來(lái)說(shuō)說(shuō)數(shù)據(jù)編碼。QR碼支持如下的編碼: 假如我們有個(gè)HELLO WORLD的字符串要編碼,根據(jù)上面的示例二,我們可以得到下面的編碼 我們還要加上結(jié)束符: 按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é)。 生成二維碼圖片首先,先把Position Detection圖案畫在三個(gè)角上。(無(wú)論Version如何,這個(gè)圖案的尺寸就是這么大) 然后,再把Alignment圖案畫上(無(wú)論Version如何,這個(gè)圖案的尺寸就是這么大) 關(guān)于Alignment的位置,Table-E.1的定義表(部分) 下圖是根據(jù)上述表格中的Version8的一個(gè)例子(6,24,42) 接下來(lái)是Timing Pattern的線 再接下來(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如下表所示: 再接下來(lái)是Version Information(版本7以后需要這個(gè)編碼),下圖中的藍(lán)色部分。 Version Information一共是18個(gè)bits,其中包括6個(gè)bits的版本號(hào)以及12個(gè)bits的糾錯(cuò)碼,下面是一個(gè)示例: 而其填充位置如下: 然后是填接我們的最終編碼,最終編碼的填充方式如下:從左下角開(kāi)始沿著紅線填我們的各個(gè)bits,1是黑色,0是白色。如果遇到了上面的非數(shù)據(jù)區(qū),則繞開(kāi)或跳過(guò)。 這樣下來(lái),我們的圖就填好了,但是,也許那些點(diǎn)并不均衡,如果出現(xiàn)大面積的空白或黑塊,會(huì)告訴我們掃描識(shí)別的困難。所以,我們還要做Masking操作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ò)后的二維碼就成最終的圖了。 這里同樣有幾個(gè)有趣的小知識(shí)點(diǎn)。 首先,二維碼不但只有黑白色的,普遍使用黑白色是為了提高其工作效率。 其次,二維碼源于日本,但在我國(guó)被發(fā)揚(yáng)光大。 |
|