二維碼詳解
一、二維碼的分類
二維碼,從字面上看就是用兩個維度(水平方向和垂直方向)來進行資料的編碼,條形碼只利用了一個維度(水平方向)表示資訊,在另一個維度(垂直方向)沒有意義,所以二維碼比條形碼有著更高的資料儲存容量。
從形成方式上,二維碼可以分為兩類,
1、堆疊式二維碼:在一維條形碼的基礎上,將多個條形碼堆積在一起進行編碼,常見的編碼標準有PDF417等
圖1 PDF417碼示例
2、矩陣式二維碼:在一個矩陣空間中通過黑色和白色的方塊進行資訊的表示,黑色的方塊表示1,白色的方塊表示0,相應的組合表示了一系列的資訊,常見的編碼標準有QR 碼,漢信碼等
圖2 QR碼示例 圖3 漢信碼示例
PDF417由美國研發,在美國地區使用廣泛
漢信碼由中國自主研發,目前已在政府相關領域得到初步的使用。
QR碼由日本研發,目前很多的應用都是用QR碼進行編碼,譯碼
目前使用最廣的是QR碼,所以接下來的內容會對QR碼進行講解,下文中提到的二維碼,指的就是QR碼
QR碼分為40個版本,版本1由21x21個方塊組成,每個版本增加4個方塊,版本40由177x177個方塊組成。每增加一個版本,QR碼可儲存的資訊數量也隨之增多。
版本1的二維碼最多可以儲存25個字元或41個數字,而版本40的二維碼最多可以儲存4296個字元或7089個數字
二、二維碼的結構
一個二維碼可以分為兩個部分,功能圖形和編碼區域
圖4
功能圖形起到定位的作用
位置探測圖形:由三個黑白相間的大正方形巢狀組成,分別位於二維碼左上角、右上角、左下角,目的是為了確定二維碼的大小和位置。
定點陣圖形 :由兩條黑白相間的直線組成,便於確定二維碼的角度,糾正扭曲。
校正圖形 :僅在版本2以上存在,由三個黑白相間的小正方形巢狀組成,便於確定中心,糾正扭曲。
資料區記錄了具體的資料資訊,糾錯資訊與版本資訊。
資料和糾錯碼:記錄了資料資訊和相應的糾錯碼,糾錯碼的存在使得當二維碼的資料出現允許範圍內的錯誤時,也可以正確解碼。
版本資訊 :僅在版本7以上存在,記錄具體的版本資訊。
格式資訊 :記錄使用的掩碼和糾錯等級。
此外二維碼的外圍還留有一圈空白區,主要是為了便於識別而存在。
三、資料編碼與例項
針對不同的資料,QR碼設計了不同的資料編碼編碼方式,我們可以根據資料的種類選擇合適的編碼方式進行編碼。
數字編碼(Numeric) :可編碼0-9,10個數字,如果需要編碼的數字的個數不是3的倍數,最後剩下的1或2位數會被轉成4或7bits,其它的每3位數字會根據不同版本被編成 10,12,14bits
字元編碼(Alphanumeric) :可編碼0-9,大寫的A-Z,以及9個其他的字元(space $ % * + – . / :);
8位位元組模式(8-bit Byte) :可編碼JIS X 0201的8位Latin/Kana字符集
除此之外,QR還提供了其他的編碼方式,每一個編碼方式都有其獨有的id進行標識,這些標識會記錄在資料區的前端,使得解碼器可以根據二維碼使用的編碼方式對資料進行解碼
圖5 一些編碼方式及其標識
糾錯碼
二維碼存在4個級別的糾錯等級,每個糾錯級別可修正的錯誤與標識見圖6,糾錯級別越高,可以修正的錯誤就越多,需要的糾錯碼的數量也變多,相應的可儲存的資料就會減少,版本1的二維碼在L級別下可儲存25個字元,在H級別下只能儲存10個字元。
圖6
下面給一個01234567在版本1下用數字編碼(Numeric),選擇的糾錯級別是M的示例
第一步,將定點陣圖案放到二維碼中
圖7
第二步:進行資料編碼
根據圖8,版本1下,採用Numeric Mode編碼時,每三個數字需要10個bits進行標示
圖8
012 ->0000001100
345 ->0101011001
67 ->1000011
組合起來為
0000001100 0101011001 1000011
在資料的頭尾加上一些標準要求的資訊
頭
數字個數 (8) = 0000001000
編碼格式 =0001
尾
終止符 =0000
組合起來為
0000001100 0101011001 1000011->
0001 0000001000 0000001100 0101011001 1000011 0000
按8bit一組重新排列,末尾不足的補零
0001 0000001000 0000001100 0101011001 1000011 0000->
00010000 00100000 00001100 01010110 01100001 10000000
不足最大bit的新增補齊碼(11101100 00010001),版本1 M下需要128bits
00010000 00100000 00001100 01010110 01100001
10000000->
00010000 00100000 00001100 01010110 01100001
10000000 11101100 00010001 11101100 00010001
11101100 00010001 11101100 00010001 11101100
00010001
第三步:新增糾錯碼
糾錯碼根據資料利用RS演算法來進行計算,篇幅所限,這裡就不具體講解了,最終的結果如下:
00010000 00100000 00001100 01010110 01100001
10000000 11101100 00010001 11101100 00010001
11101100 00010001 11101100 00010001 11101100
00010001->
00010000 00100000 00001100 01010110 01100001
10000000 11101100 00010001 11101100 00010001
11101100 00010001 11101100 00010001 11101100
00010001 10100101 00100100 11010100 11000001
11101101 00110110 11000111 10000111 00101100
01010101
第四步:將最終的資料編碼按順序放入二維碼中
圖9 圖10
從左下角開始,1為黑色,0為白色,按順序依次填入二維碼中
第五步:新增格式資訊和進行掩碼運算
得到的影象還需要對資料區進行掩碼運算,掩碼運算的目的是讓影象中黑色和白色方塊分佈的更加均勻一些,便於解碼
有以下幾種掩碼運算,相應的標識和變換方式見圖11,二維碼的左上角的座標為(0,0)
圖11
圖12 座標系和掩碼運算的圖案
這裡我們選擇標識為011的掩碼
格式資訊的組成為 :糾錯標識+掩碼標識+BCH糾錯碼
所以前面的糾錯標識+掩碼標識為:00011
BCH糾錯碼計算為:
得到糾錯碼為 :011 0101 1001
格式資訊為 :00011 1101011001
為了避免選擇標識00的糾錯類別和標識000的掩碼運算,照成格式資訊為全0的數字,所得的格式資訊還要與101010000010010做異或運算
000111101011001
101010000010010 XOR
101101101001011
最終的格式資訊為 :101101101001011
將格式資訊放入二維碼中
圖13
對加格式資訊後的二維碼 進行掩碼運算
得到的最終二維碼,儲存的資料資訊是01234567
圖14
整個流程見圖15
四、二維碼的安全知識
雖然二維碼本身承擔的只是一些文字資料,但仍會導致一些安全問題
1、攻擊者將一些惡意網站或者一些惡意程式碼製作成二維碼,使用者掃描後,會自動下載一些惡意軟體,或跳轉到一些虛假網站給使用者造成危害,
3、如果將一些敏感資訊不加密而直接儲存在二維碼中,便會存在資訊洩露的可能,比如11年火車票上的二維碼就存在洩露使用者的身份證號碼的問題。
五、總結
雖然我們在使用二維碼的時候只需要用手機一掃即可,但二維碼的編碼和解碼卻包含了很多的步驟和很多的知識,此外二維碼本身僅僅是資料的承載體,我們在使用時要針對一些敏感資訊進行加密處理,防範潛在的攻擊方式
參考文獻