二維碼的生成原理和工作原理

二維碼由來

在1994年,這個類似於一個正方形馬賽克的圖片由日本DENSO WAVE公司發明----兩位程序員為了追蹤汽車零部件而設計。而現在,應用更為廣泛的是由美國人設計的pdf417,datamatrx..其中的pdf417是由留美華人王寅敬博士發明。

其實很長時間裡二維碼應用於產品追蹤,物品識別和庫存管理等工業用途。直到智能手機和微信在中國普及,二維碼才變成了一個可以被大眾隨時“掃一掃”的工具,或者說人人手裡都有了一個“二維碼掃描器”。二維碼在中國應用的範圍比較廣,而在網上支付方面,二維碼也存在一定的風險。其實,直接掃碼很危險。有網友稱其在街頭張貼的廣告上掃描了一個二維碼之後, 手機剛充的100元話費就不翼而飛。他掃描了一個貼在牆上的交友類二維碼後,並未下載安裝交友軟件,然後就被通知手機欠費。結果檢測手機發現,被安裝了手機病毒軟件,導致剛充的話費被偷走。央行在2014年叫停二維碼支付後時隔兩年,於2016年8月3日官方才重新承認二維碼的支付地位。

生成原理:

該原理是,用特定的幾何圖形按編排規律在二維方向上分佈,採用黑白相見的圖形來記錄數據符號信息。

為了利用計算機內部邏輯,用數字“0”和數字“1”作為代碼,同時使用若干個與二進制相對應的幾何形體表示文字數值信息。

二維碼的生成原理和工作原理

這裡面我有幾個小知識點想提一提。

知識點一:二維碼共有40個尺寸

也就是版本version,Version 1.0是21 x 21的正方形,Version 2.0是 25 x 25的(公式:(V-1)*4 + 21)。所以最大的尺寸就是177 x 177 的正方形。

知識點二:三個點確定一個面

二維碼只有三個角上有位置探測圖案,就是這個就是為了更好的讀取二維碼。那有人問為什麼不是四個能,這個角也不是多餘的,可以鑲嵌別的信息。

知識點三:旋轉二維碼,也可以識別

因為有知識點二中所說的位置探測圖案和分隔符,所以,無論是正著掃碼,還是豎著掃碼,或者斜著掃碼,信息都可以被識別。

再來看看,二維碼的工作原理:

通過常見的圖象輸入設備或光電掃描設備,它們可以自動讀取,並且會對識別出的信息進行自動處理。

因為每個碼制有自己的字符集,一個一個的字符佔據自己的位置。所以,通過掃描能讀取的數據信息在二維碼中的位置是由定位圖形和分隔符決定的。才能夠快速地識別和處理圖形旋轉、變化等問題。

二維碼可以在水平和豎直方向上進行編碼,用正方形的黑白格來記錄信息,原理是利用了二進制的0和1,打個比方,現在有一個10乘10格子的二維碼,每一行都有黑白格,如果用1表示白色的格子,0表示黑色的格子,那麼我們可以用類似“0100101100”這樣的一行數字來表示每一行的代碼,那麼將10個這樣的數字行排列起來,就組成了一個二維碼,我們掃碼就相當於解碼的過程,可以識別二維碼上的信息。

二維碼還具有容錯性,一些二維碼只需要掃前面幾行就可以識別出信息,哪怕二維碼局部破損丟失都可能識別信息,不需要掃全,它比普通條形碼譯碼錯誤率50萬分之1還要低,誤碼率低於1000萬分之1。

數據編碼

我們先來說說數據編碼。QR碼支持如下的編碼:

二維碼的生成原理和工作原理

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

二維碼的生成原理和工作原理

我們還要加上結束符:

二維碼的生成原理和工作原理

按8bits重排

如果所有的編碼加起來不是8個倍數我們還要在後面加上足夠的0,比如上面一共有78個bits,所以,我們還要加上2個0,然後按8個bits分好組:

00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 01000000

補齊碼(Padding Bytes)

最後,如果如果還沒有達到我們最大的bits數的限制,我們還要加一些補齊碼(Padding Bytes),Padding Bytes就是重複下面的兩個bytes:11101100 00010001 (這兩個二進制轉成十進制是236和17,我也不知道為什麼,只知道Spec上是這麼寫的)關於每一個Version的每一種糾錯級別的最大Bits限制,可以參看QR Code Spec的第28頁到32頁的Table-7一表。

假設我們需要編碼的是Version 1的Q糾錯級,那麼,其最大需要104個bits,而我們上面只有80個bits,所以,還需要補24個bits,也就是需要3個Padding Bytes,我們就添加三個,於是得到下面的編碼:

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

上面的編碼就是數據碼了,叫Data Codewords,每一個8bits叫一個codeword,我們還要對這些數據碼加上糾錯信息。

糾錯碼

上面我們說到了一些糾錯級別,Error Correction Code Level,二維碼中有四種級別的糾錯,這就是為什麼二維碼有殘缺還能掃出來,也就是為什麼有人在二維碼的中心位置加入圖標。

錯誤修正容量

L水平7%的字碼可被修正

M水平15%的字碼可被修正

Q水平25%的字碼可被修正

H水平30%的字碼可被修正

那麼,QR是怎麼對數據碼加上糾錯碼的?首先,我們需要對數據碼進行分組,也就是分成不同的Block,然後對各個Block進行糾錯編碼,對於如何分組,我們可以查看QR Code Spec的第33頁到44頁的Table-13到Table-22的定義表。注意最後兩列:

Number of Error Code Correction Blocks :需要分多少個塊。

Error Correction Code Per Blocks:每一個塊中的code個數,所謂的code的個數,也就是有多少個8bits的字節。

生成二維碼圖片

二維碼的生成原理和工作原理

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

二維碼的生成原理和工作原理

然後,再把Alignment圖案畫上(無論Version如何,這個圖案的尺寸就是這麼大)

二維碼的生成原理和工作原理

關於Alignment的位置,Table-E.1的定義表(部分)

二維碼的生成原理和工作原理

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

二維碼的生成原理和工作原理

接下來是Timing Pattern的線

二維碼的生成原理和工作原理

再接下來是Formation Information,下圖中的藍色部分。

二維碼的生成原理和工作原理

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

二維碼的生成原理和工作原理

這15個bits中包括:

5個數據bits:其中,2個bits用於表示使用什麼樣的Error Correction Level, 3個bits表示使用什麼樣的Mask

10個糾錯bits。主要通過BCH Code來計算

然後15個bits還要與101010000010010做XOR操作。這樣就保證不會因為我們選用了00的糾錯級別和000的Mask,從而造成全部為白色,這會增加我們的掃描器的圖像識別的困難。

下面是一個示例:

二維碼的生成原理和工作原理

關於Error Correction Level如下表所示:

二維碼的生成原理和工作原理

再接下來是Version Information(版本7以後需要這個編碼),下圖中的藍色部分。

二維碼的生成原理和工作原理

Version Information一共是18個bits,其中包括6個bits的版本號以及12個bits的糾錯碼,下面是一個示例:

二維碼的生成原理和工作原理

而其填充位置如下:

二維碼的生成原理和工作原理

然後是填接我們的最終編碼,最終編碼的填充方式如下:從左下角開始沿著紅線填我們的各個bits,1是黑色,0是白色。如果遇到了上面的非數據區,則繞開或跳過。

二維碼的生成原理和工作原理

這樣下來,我們的圖就填好了,但是,也許那些點並不均衡,如果出現大面積的空白或黑塊,會告訴我們掃描識別的困難。所以,我們還要做Masking操作QR的Spec中說了,QR有8個Mask你可以使用,如下所示:其中,各個mask的公式在各個圖下面。所謂mask,說白了,就是和上面生成的圖做XOR操作。Mask只會和數據區進行XOR,不會影響功能區。(注:選擇一個合適的Mask也是有算法的)

二維碼的生成原理和工作原理

其Mask的標識碼如下所示:(其中的i,j分別對應於上圖的x,y)

二維碼的生成原理和工作原理

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

二維碼的生成原理和工作原理

Mask過後的二維碼就成最終的圖了。

這裡同樣有幾個有趣的小知識點。

首先,二維碼不但只有黑白色的,普遍使用黑白色是為了提高其工作效率。

其次,二維碼源於日本,但在我國被髮揚光大


分享到:


相關文章: