QR code 二維碼基礎入門教程
時間 2021-07-13
標籤
qrcode
二維碼
教程
QR code 二維碼基礎入門教程
Introduction
History and Information
- QR code 於 1994 年,由 日本公司 Denso-Wave 發明。其標準爲ISO/IEC 18004:2006
- QR code 最小爲 21*21,最大爲177*177,其大小被稱爲「Version」
- Version=1, 21*21
- Version=2, 25*25
- Version=3, 29*29
- ……………
- Version=40, 177*177
- 計算公式:(V-1)*4+21。其中V爲版本號
- QR code 有4種糾錯等級,可恢復的碼字比例爲
Error Correction Level |
Error Correction Capability |
L |
恢復7%的數據 |
M |
恢復15%的數據 |
Q |
恢復25%的數據 |
H |
恢復30%的數據 |
- 數據模式包括:數字模式,數字字母模式,8字節模式,日本漢字模式,擴充解釋模式(ECI),結構鏈接模式,FNC1模式 (實際上不同的標準支持的模式類型不同,我們不妨從簡單的開始,重點關注前4種模式)
General Overview of Creating a QR Code
- 數據分析。對需要編碼的數據進行分析,然後選擇最佳的模式
- 數據編碼。根據步驟1的模式,對數據進行編碼
- 糾錯編碼。生成糾錯碼
- 構造最終消息。填充數據碼和糾錯碼填入矩陣
- 在矩形中放置模塊。將尋像圖形、分隔符等一起放入矩陣
- 掩摸。用8中掩摸對編碼區域圖形做XOR,評價8種結果,選擇最優的一種
- 格式和版本信息。生成版本信息和格式信息
接下來,我們對每個步驟進行說明
數據分析
- 數據編碼將輸入數據編碼爲一串0/1比特流,選擇合適的數據模式,能夠這串流盡量的短
- 各個模式可編碼的字符
- 數字模式:數字0-9
- 數字字母模式:數字0-9,所有大寫字母,符號 $ % * + - . / : 還有空格。具體請看數字字母模式譯碼錶
- 8字節模式:默認情況下,可編碼 ISO-8859-1 所有字符
- 日本漢字模式(Kanji,或者叫雙字節模式):編碼Shift JIS。也可以編碼UTF-8,但是需要的字節可能更多。
- 擴充解釋模式:可指定缺省字符集(這裏我們不討論這種模式)
- 結構鏈接模式:可以將一個數據編碼爲多個QR code(最多16個,這裏我們不討論這種模式)
- FNC1模式:允許QR code像GS1 code一樣(這裏我們不討論這種模式)
- 如何選擇合適的模式
- 輸入數據都是數字,選擇數字模式
- 當數字模式不滿足且輸入數據都在數字字母模式譯碼錶時,選擇數字字母模式(注意:數字字母模式只能編碼大寫字母)
- 輸入數據不在數字字母模式譯碼錶,但都在ISO-8859-1是,選擇8字節模式
- 如何選擇合適的模式Plus,摘自QR Code二維碼–一種新型的矩陣符號 27頁
下列導則可以形成對給定的輸入數據決定最短位流的算法的基礎。在方括號中的字符數如[5,7,9]分別用於版本1~9,版本10~26和版本27~40.在導則中,術語「專有子集」是指一種模式的字符集中的一組字符,不能與另一種更有限的字符集共享,例如,8位字節字符集的專有子集由JIS
8的值
00HEX
~
FFHEX
組成,但它不包括十六進制的值
20,24,25,2A,2B,2D~3D和41~5A;因爲它們是字符字符集的一組字符{A~Z,space,$,%,*,+,-,’, /,:}
- 混合多種模式(這裏不討論這種模式)
- 選擇好了合適的模式,接下來是數據編碼
數據編碼
Step 1 選擇糾錯等級
Error Correction Level |
Error Correction Capability |
L |
恢復7%的數據 |
M |
恢復15%的數據 |
Q |
恢復25%的數據 |
H |
恢復30%的數據 |
- 糾錯等級越高,糾錯碼就越多,那麼可編碼的數據就變少,因此QR code的版本可能要更大
Step 2 確定數據的最小版本
編碼模式 |
最大可編碼字符數(糾錯等級L,版本40) |
數字模式 |
7089 |
字母數字模式 |
4296 |
8字節模式 |
2953 |
日本漢字模式 |
1817 |
Step 3 添加模式指示符
- 比特流最前面是模式指示符,模式指示符是一個4比特的指示符,指示符如下
編碼模式 |
模式指示符 |
數字模式 |
0001 |
數字字母模式 |
0010 |
8字節模式 |
0100 |
日本漢字模式 |
1000 |
ECI模式 |
0111 |
- 國標的指示符長這樣:
Step 4 添加字符計數指示符
- 將輸入數據的字符數 編碼爲一串指示符。不同版本字符數字指示符的長度不一樣。
- 舉個例子:HELLO WORLD,版本1,模式=字母數字模式,字符數=11,那麼字符計數指示符的長度爲9個比特。11的二進制:1011,不滿9位則左邊填充0,得到 000001011。結合上一步的模式指示符,當前編碼比特流爲:0010 0000001011
Step 5 利用模式對輸入數據編碼
- 不同模式的編碼方式不同,通過具體例子我們來不同模式的熟悉編碼過程
數字模式編碼
- 將輸入數據分爲3位一組。8675309 -> {867, 530, 9}
- 將每組數據轉爲二進制,如果一組數據是3個,那麼轉換爲10位二進制,如果是2位,轉換爲7位,如果是1位,轉換爲4位
- 867 -> 1101100011
- 530 -> 1000010010
- 9 -> 1001
字母數字模式編碼
- 將輸入數據分爲2個一組。HELLO WORLD -> {HE, LL, O , WO, RL, D}
- 通過查表 字母數字模式的編碼/譯碼錶,將數據轉爲對應的值。{{17,14}, {21,21}, {24,36},{32,24},{27,21},{13}}
- 每組的第一個數乘上45,然後加上第二個數。{17,14} -> 17*45+14=779。
- 將3得到的結果轉爲11位二進制。779 -> 01100001011
- 如果只有一個字符,,轉換爲6位二進制。{D} -> {13} -> 001101
- 重複3-5步,得到結果 01100001011 01111000110 10001011100 10110111000 10011010100 001101
8字節模式
- 默認字符集爲ISO 8859-1。如果輸入字符不在ISO 8859-1中,可轉換爲UTF-8。
- 通過查表,將輸入數據轉爲16進制。例如,」Hello, world!」
- H → 0x48
- e → 0x65
- l → 0x6c
- l → 0x6c
- o → 0x6f
- , → 0x2c
- → 0x20
- w → 0x77
- o → 0x6f
- r → 0x72
- l → 0x6c
- d → 0x64
- ! → 0x21
- 將十六進制轉爲二進制
- H → 0x48 → 01001000
- e → 0x65 → 01100101
- l → 0x6c → 01101100
- l → 0x6c → 01101100
- o → 0x6f → 01101111
- , → 0x2c → 00101100
- → 0x20 → 00100000
- w → 0x77 → 01110111
- o → 0x6f → 01101111
- r → 0x72 → 01110010
- l → 0x6c → 01101100
- d → 0x64 → 01100100
- ! → 0x21 → 00100001
日本漢字模式
編碼結果
模式指示符 |
字符計數指示符 |
編碼序列 |
0010 |
000001011 |
01100001011 01111000110 10001011100 10110111000 10011010100 001101 |
Step 6 填充空餘的比特位
- 通過查表error correction table得到最大數據比特位數。例如,1-Q共有13個碼字,每個碼字有8位,因此最大數據比特位數:13*8=104
- 添加終止符。終止符位4比特長度:0000。但是如果編碼序列爲102,只剩下2位,那麼只需要填充2位的0。添加了終止符後的編碼序列爲
模式指示符 |
字符計數指示符 |
編碼序列 |
終止符 |
0010 |
000001011 |
01100001011 01111000110 10001011100 10110111000 10011010100 001101 |
0000 |
如果當前編碼序列的最後一個碼字不滿8位,那麼填充0至8位
當前數據:00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 010000
填充後的數據:00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 010000 00
如果當前數據太短了,沒有填滿最大比特位數,那麼重複填充 11101100 00010001
最終數據: 00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 010000 00 11101100 00010001 11101100
最後,用一張圖來總結以上過程