QRCode二維碼編解碼原理

目錄:

前置知識
encode
decode

有任何問題和指導建議,可以聯系我討論:guchenhui1993@gmail.com

前置知識

  • 不同碼制:

    Data Matrix,MaxiCode, Aztec,QR Code, Vericode,PDF417,Ultracode,Code 49,Code 16K等

  • 根據原理分類:

    堆疊式/行排式以及矩陣式。本文講的是日常生活最常見的矩陣式QR Code.

    • 堆疊式/行排式:

    編碼原理建立在一維條碼基礎之上,按需要堆積成二行或多行。代表的碼制有:
    Code 16K、Code 49、PDF417、MicroPDF417等.

    • 矩陣式:

    在一個矩形空間通過黑、白像素在矩陣中的不同分布進行編碼。有占位表示1,無占位表示0.代表的碼制有:
    Code One、MaxiCode、QR Code、 Data Matrix、Han Xin Code、Grid Matrix等.

  • 尺寸:

    二維碼一共有40個尺寸(Version)。Version 1是21 x 21的矩陣,Version 2是 25 x25的矩陣,每增加一個version,就會增加4的尺寸,公式:(V-1)*4+21.

    看下圖:


    Version 40是這樣的,真是令人害怕,來五個這樣的二維碼即可存下《浮生六記》的閨房記樂:


  • 信息容積

    • 數字:最多7089字符
    • 字母:最多4296字符
    • 8位二進制數:最多2953字符
    • 日文漢字:最多1817字符
  • 格式信息:

    • 表示形式是V-E,V是前面提到的version,E是容錯級別,分別是:L(7%),M(15%),Q(25%),R(35%).
  • 容錯:

    允許存儲的二維碼信息出現重復部分,級別越高,重復信息所占比例越高。

  • 結構圖:

  • Position Detection Patterns:

三個相同的探測圖形,用于定位視圖和方向,位于左上角、右上角、左下角.符號中遇到類似圖形的可能性極小,可以在有效識別到二維碼。

  • Separators:
    每個探測圖形和編碼區域之間有一條1單位寬度的分隔符.由白色塊組成.

  • Timing Pattern:
    黑白色相間交替組成的一行一列兩條位于橫縱的兩兩探測圖形之間,用于確定符號的密度和版本,提供決定模塊坐標的基準位置.

  • Alignment Patterns:
    類似小號的探測圖形,中心矩形邊框變為1單位,這種校正圖形的數量由version來定,大于version 1的都有該校正圖形.

  • Encoding region:
    包含數據碼字,糾錯碼字,版本信息,格式信息,符號字符等數據。

  • Quiet zone:
    環繞整個二維碼四周的4單位寬的區域.白色.

encode

數據分析-->數據編碼-->糾錯編碼-->構造最終數據-->構造矩陣-->打上掩碼-->填充格式與版本信息

  • 數據分析:

    分析輸入的數據流,確定編碼的字符類型,按相應的字符集轉換成符號字符;選擇糾錯等級;如果沒有指定version,會采用能表示目標信息的最小version.

    字符類型的編號(中文是1101,終止符是0000):

    各尺寸的數據組成細節:

  • 數據編碼

    將數據字符轉換為位流,每8位一個碼字,整體構成一個數據的碼字序列.必要的時候需加入填充字符以填滿按照版本要求的數據碼字數.

    先看看不同version下數據長度對應的編碼的位數約定:

    支持如下編碼:

    • Numeric mode|數字編碼:

      數據類型編碼(4位)+數據長度編碼(根據version轉成10或12或14位二進制數)+從左到右,
      每3個數字為一組,轉成10位二進制數,剩下不滿三位的轉成4或7位二進制數。

      比如1314520:

      • 131 452 0
      • --> 131(0010000011) 452(0111000100) 0(0000)
      • --> 數字長度7 -->0000000111
      • --> 由上面數據分析的圖,數字的編碼是0001
      • --> 0001 0000000111 0010000011 0111000100 0000 0000(結束符)

      公式B=4+C+10(D DIV 3)+R.

    • Alphanumeriv mode|字符編碼:09,AZ,以及一些符號和空格。

      編碼方式和數字編碼類似,區別是以2個字符為一組,轉成11位二進制數,不滿2個字符的轉成6位。(a,b)-->a*45+b-->binary

      公式B = 4 + C + 11(D DIV 2) + 6(D MOD 2).

    • Byte mode|字節編碼:

      公式B = 4 + C + 8D.

    • Mixing mode|混合編碼

      各種類型的組合編碼。

    • Kanji mode|日文編碼(不具體展開)
    • ECI mode|特殊字符集(不具體展開)
    • Structured Append mode|附加結構編碼(不具體展開)
    • FNC1 mode|特殊工業或行業使用(不具體展開)

8bit重排:接下來會對二進制比特流按照8位重排,編碼總位數如果不是8的倍數,需要在末尾補0.

補齊碼:每個字碼是8位,重排補0以后,如果字碼的長度沒有到達該version的容量,需要在后面加上補齊碼。
具體姿勢是不斷重復11101100和00010001這兩個碼字。

  • 糾錯編碼

    為了能被糾錯算法處理,將解析出的碼字序列分塊。然后把糾錯碼字拼到數據碼字后面。有上文提到的L,M,Q,H四種糾錯級別.

    • 糾錯算法:

      可糾正兩種類型的錯誤,拒讀錯誤(錯誤碼字的位置已知)和替代錯誤(錯誤碼字的位置未知).拒讀錯誤是沒有掃描到或者無法譯碼的字符,替代錯誤是錯誤譯碼的字符。一個替代錯誤需要兩個糾錯碼字來糾正。

      這里有個公式:e + 2t <= d - p

      e:拒讀錯誤數 t:替代錯誤數 d:糾錯碼字數 p:錯誤譯碼保護碼字

      主要通過里德-所羅門糾錯算法 來實現。
      涉及到伽羅瓦域中的多項式算法等數學理論。這邊還需要深入學習。寫個//TODO_NEXT_TIME

      官方的除法電路圖示是這樣的:

  • 構造最終數據信息

    將數據碼字的塊和糾錯碼字的塊以行列交織的方式排列。

    經過上一步計算出糾錯碼以后得到類似這樣的結果:

    左邊是數據碼字,右邊是糾錯碼字。然后按列排列成:

    D1, D12, D23, D35, D2, D13, D24, D36, ... D11, D22, D33, D45, D34, D46, E1, E23, E45, E67, E2, E24, E46, E68, ... E22, E44, E66, E88.

  • 構造矩陣

    將碼字模塊以及探測圖形、分隔符、定位圖形、校正圖形填充到矩陣相應位置中。具體位置如圖:

    以及校驗圖形的位置:

    QR Code中,符號字符以2個單位寬的縱列從符號的右下角開始布置,并且自右向左,自底向上。每個碼字最高位應放在第一個可用的位置,中途遇到障礙就跳過,在障礙物上面或者下面繼續填充。



  • 打上掩碼

    為了可靠性,使用掩碼圖形讓矩陣中的黑白色塊比例接近1:1并均勻分布,盡可能避免探測圖形出現在別的區域.所以每個二維碼咋一看,都是一模一樣。

    有幾點需要說明

    • 不會影響功能區(Function Patterns)
    • 對編碼區域(Encoding Region)進行XOR運算(按照掩碼的黑色部分顏色取反)
    • 對結果圖不符合人意的部分計分
    • 評估后選擇最佳的掩碼(分數最低的那個)

    關于掩碼方案優劣的評分標準(N1=3, N2=3, N3=40, N4=10):


    掩碼標識碼:

    八種掩碼:


    大致步驟如下:


  • 填充格式與版本信息

    • 生成格式和版本信息填入矩陣相應的區域上。

      • 格式信息:格式信息15位,5個數據位10個糾錯位。數據位中前兩位是糾錯等級:

      第三到第五位是掩碼標識。然后根據糾錯算法算出10位糾錯碼,加載五位數據位后面。

      • 版本信息:版本信息18位,6位數據位12位糾錯位。version 7~40時才有版本信息,沒有任何版本信息的結果全是0,不用對版本信息做掩碼。

decode

encode的逆向流程:

  • 定位并獲取圖形,根據黑白色塊轉成0,1組成的數組,確定一個閾值,用該值將圖像轉化為一系列深色和淺色像素
  • 識別格式信息
  • 識別version信息
  • 去掉掩碼,即從格式信息中得到編碼區的擺位圖進行異或處理消除掩碼
  • 恢復數據碼字和糾錯碼字
  • 使用糾錯碼字進行錯誤檢查,并糾錯
  • 解碼數據碼字
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容