公众号文章精选

肉眼識別二維碼?你也可以


肉眼識別二維碼?你也可以


按:一個開關的開合狀態可以對應“0、1”兩個信號,萊布尼茨三百多年前留下的這個制式影響深遠。日常語言依賴于思維邏輯,與之類似,數字語言的流通則依賴於數學邏輯,但本質上仍然只是無數個與非門的邏輯計算。因此相比於計算機,我們的計算能力雖然在效率方面有點難以啟齒,但這並不代表有些事情我們註定辦不到。


比如靠肉眼識別二維碼?雖然人類大腦的計算效率早已落後家用計算機好幾個量級,但這並不妨礙我們光靠人腦去完成一件“看似只有電子設備才能完成的事情”的嘗試。


畢竟生活已經夠無聊了。


本文由與每天掃碼支付都有獎勵的支付寶聯合出品

支付就用支付寶



掃碼還得靠手機





我們在生活中消費、轉賬時用手機掃的二維碼,屬於QR code(Quick Response)。但除了QR code之外,二維碼還有其他多種制式標準,比如Data Matrix、PDF417、Ultra-code——本文只討論QR碼這個生活場景中最常見的二維碼制,因為……其他的我也不會。


條碼技術最早需要追溯到上世紀20年代,當時美國威斯汀豪斯(Westinghouse)實驗室的發明家約翰·科芒德(John Kermode)為了實現對郵政單據的自動分檢,發明了一種用條碼對單據做標記的機制(一個條表示數字“1”,二個條表示數字“2”,稱為模塊比較法),以及相應的譯碼器。


但是這種始祖鳥級別的制式所蘊含的信息量極低,不久后科芒德的合作者道格拉斯·楊(Douglas Young)對此進行了改進,利用黑條之間空隙的尺寸變化來編碼數據。兩人在1949年獲得了世界上第一個條碼專利,這種最早期的條碼由黑白相間的同心圓組成,被稱為牛眼式條碼


肉眼識別二維碼?你也可以

另一說法稱,牛眼式條紋是由工程師諾曼·伍德蘭(Norman J. Woodland)發明的


現如今,我們已經對掃碼購物的行為非常習慣了,但在條碼技術普及之前,超市的出納員只能靠敲鍵盤來輸入商品價格,操作成本高不說,患有腱鞘炎的人也不在少數,簡直成了職業病。條碼技術的出現無疑節省了很多工作成本,更何況條碼本身也伴隨着硬件技術實現一次次的更迭和普及。


欲求不滿是人類的美好品德。條形碼雖然帶來了極大的便利,但是容量依舊有限,只容納20個英文和數字,且無法編碼漢字和假名。當時的制碼人員幾乎分成了兩類,一類研究怎麼往條碼里塞更多的信息,一類研究怎麼更快解碼。大多數人屬於第一類,而當時正在日本豐田子公司DensoWave從事條形碼讀取機研發的原昌宏開始嘗試研發更快速的編碼制式,進過一年半的研發過程,才有了1994年QR code碼制的發明。


碼如其名,這一碼制的最大特點便是“Quick Response”——快速響應,讀取速度比其他編碼制式快10倍以上,最先被用在汽車零部件生產行業的電子看板管理(負責傳遞信息和生產管理的系統之一)中,大大提高了生產、出貨乃至單據的管理效率。


作為一個男性程序員,原昌宏對於“快”有着獨特的理解。他認為要想在應用條碼的過程中實現快速,核心是解決識別的問題,剩下的內容只是計算。


——如何才能讓機器快速找到目標碼區?

用特殊形狀的符號標記區域。——

——如何確定碼區所在平面?

用三個特殊形狀的標記(三點確定一個平面)。——

——如何確定機器讀取碼區的方向?

設置好從某一標記出發,以及出發的方向就可以了。——


邏輯沒有問題,剩下要解決的就是標記的形狀。如果編碼周圍有相同的圖案,讀取時就會被誤認為是編碼信息,從而導致誤讀,因此定位圖案一定要保證特殊性。原昌宏為此收羅了大量廣告單、雜誌等印刷品,從各個方向進行掃描,並做了黑白色的二值處理,分析黑白佔比,從而得出結論:黑白間隔比為1:1:3:1:1的比例定位的時,在印刷品中出現的概率最低。


肉眼識別二維碼?你也可以


以下方二維碼為例,三個分別位於二維碼的左上角、右上角、左下角的“回”字形符號,便是規定了尺寸、讀取方向的位置探測圖形。有這三個識別符號放在二維碼的三個角上后,解碼的時間響應就可以很快,比同時代的技術要快20倍。 這便是肉眼識別二維碼所要了解的第一個知識點:


用位置探測圖形確定碼區。


肉眼識別二維碼?你也可以


此外,該制式還規定在與位置探測圖形接壤的碼區部分均為空白,以防止對位置探測圖形產生識別干擾,這便是位置探測圖形分隔符(下圖中藍色區域)


肉眼識別二維碼?你也可以


再考慮到印有二維碼的載體在實際應用場景中可能會發生的扭曲、移位和破損,制式還規定了一種與位置探測圖形相類似的“回”字形圖案(1:1:1:1:1),用來輔助定位減少誤差,這便是校正圖形(僅在版本2以上存在)


肉眼識別二維碼?你也可以


但如果連校正圖形也被污染了呢?還有定位圖形(下圖黃色區域),這是平行於二維碼邊緣的兩條黑白交替出現的直線,與位置探測圖形分隔符相接,用於確定二維碼的角度,糾正扭曲。


肉眼識別二維碼?你也可以


上面介紹的四個圖形均屬於功能區域,都是為了保證QR碼能被讀碼設備正確獲取,不存儲具體數據信息。在學習肉眼識別二維碼的過程中,我們只要找得到它們就夠了。


那麼在剩下來的編碼區里,究竟可以存儲多少信息?答案是試規格而定。為了節省空間,QR碼符號共有40種規格的矩陣,從最小的21×21(版本1)到最大177×177(版本40),每一版本符號比前一版本每邊增加4個模塊。版本1的二維碼最多可以儲存25個字符或41個數字,而版本40的二維碼最多可以儲存4296個字符或7089個數字。


肉眼識別二維碼?你也可以


在下圖的版本1二維碼中,只有未被紅黃藍三色填充的幾塊碼區為我們所需要的數據存儲區。信息將通過特定算法轉換成黑色和白色的小方格填充其中,但即便我們知道了該看哪些區域,離最終解碼還有些距離。


肉眼識別二維碼?你也可以


再往下細分,數據存儲區又可以分成三類:數據編碼、糾錯編碼,以及代表格式字符串的碼區。第一種自然不必說,是我們最終需要使用的區域。至於糾錯編碼,這裡不得不提到QR碼的另外一大特點——高容錯率


日常生活里,沿街餐館里貼在桌角用於收款的二維碼大概是最容易受損的了。印有二維碼的小紙片這邊磨破一個角,那邊沾了點醬油,碼區可能早已不再完整。糾錯編碼的作用便體現在這裡,通過對數據碼進行RS糾錯計算(里德-所羅門碼算法)得到與之對應的糾錯碼,以此來保證二維碼的可讀性。當數據碼區受到污染的時候,讀碼器依舊可以憑藉糾錯碼得到正確信息。


根據糾錯能力的不同,糾錯碼共分成L、M、Q、H 4個級別,分別可修正7%、15%、25%、30%的字碼。關於糾錯碼的級別信息便記錄在數據區的第三塊內容——格式字符串(即下圖紅色部分),這是我們需要處理的第一組數據。


肉眼識別二維碼?你也可以



格式字符串所蘊含的信息除了糾錯等級以外,還包括表示掩碼類型的信息。所謂的掩碼,粗暴理解是為了讓二維碼更加容易被機器識別而定義的一次計算過程,降低了二維碼本身被誤讀的可能性,使整個二維碼碼區排列更均勻,更容易被識別。


QR碼制式中一共定義了7種掩碼類型,每一種又可以根據4個糾錯碼級別產生4個變種,對於同一個信息便有了4*7=28種加工可能。因此只有確定了糾錯等級和掩碼類型,才能正式進入對數據的處理階段,而我們首先需要得到的便是掩碼的類型


黑塊為“1”,白塊為“0”。格式字符串數據的翻譯方向為從上往下(或從右到左),需注意當從右往左進行翻譯的時候,右邊半段紅色區域的左端與左邊半段紅色區域的右端是重複信息,只取其中一位。基於上述算法法則,我們很快可以得到格式字符串信息(紅色區域,如上圖所示)——110011000101111,再查閱格式字符串表可得出結論:該二維碼所採用的糾錯級別為L,掩碼模式4(下圖正中所示掩碼模式)。


肉眼識別二維碼?你也可以


接下來便需要對掩碼進行逆向計算。所謂掩碼其實很好理解——這是一個把數據區里的黑白小方塊拆散的過程,每種掩碼類型所規定的圖像模型中,黑色區域表示原始碼區的該位置需要顛倒一次黑白(數值反轉),白色區域保持不變,以此來打散碼區。因此我們可以根據掩碼模式4的圖形來推算這個二維碼在掩碼處理之前的狀態。


肉眼識別二維碼?你也可以


終於等到從圖形碼變成數字的一刻。對於上圖左側我們得出的結論圖,我們定義白塊為0,黑塊為1,從最右下角的模塊開始進行記錄,可以很輕易得到一串數列。下圖是一個附帶校正圖形(紫色部分)與版本信息(藍色部分)的二維碼示意圖,紅線所示為閱讀方向。


肉眼識別二維碼?你也可以該數列為:

01000000  00110110

01010110  11100110

01000000  ……


接下來的工作便是對這串數字進行換算。無論是編碼還是解碼,我們都希望二維碼能夠以最短的比特串記錄數據,因此編碼開始之前便會對四種數據形式(數字、字母數字、漢字,8位字節)進行編碼方式的選擇,在後期得到的二進制數列中也能找到每一個編碼方式獨有的二進制標識,這些標識會記錄在數據區的前端(即圖中右下角四個小方塊的位置),使得解碼器可以根據二維碼使用的編碼方式對數據進行解碼。


編碼方式通常用4位數字錶示,因此我們單拎出開頭的4個數字“0100”,對照下表可查到對應的模式為字節模式。


肉眼識別二維碼?你也可以


8位字節模式所使用的是ASCII字符集,每個字符都需要用8位二進制碼進行表示。而在代表編碼模式的4個數字後面,我們仍需要再拎出來8個數字“00000011”,這組數字所表示的是原數據的字符數,十進製為3,即原數據共有三個字節。


因此這組數據應該這樣排列:

0100  00000011

01100101  01101110

01100100  0000……


在二維碼的解碼過程中,“0000”代表的是原始數據的結束。但QR碼對每種版本都規定了具體位數,因此後面的數據碼往往由補齊碼和大量糾錯碼組成。


補齊碼的設置其實特別有意思。在終止符出現后,需要先將位數用“0”補到8的倍數。如果還不夠,則需要往後頭重複兩組字節:11101100 、00010001。這些字節分別等於236和17,在二維碼里的地位有如開普勒常數之於太陽系,自然常數之於自然。具體為何如此規定,若悉知,望告知。


至於糾錯碼,雖然本文不多做介紹,但是由於在大容量二維碼中(版本高於4),最後呈現出來的碼是通過將數據碼和糾錯碼進行重新排布,再套用掩碼模型製作出來的,因此無法用前文的方法進行計算。


最後的最後,我們最後倒騰出來的三組字節換算成10進制後分別是101、110、100,查詢下表就可以看到這張二維碼的數據信息,肉眼識別二維碼——目標達成。


     至於支付,真的還是用支付寶吧     


自2011年首次將掃碼支付引入國內以來,支付寶藉助智能手機行業的高速發展迅速成長,從條碼到二維碼甚至到無人商店,至今已然重塑了很大一部分人的支付習慣。無論是吃飯購物,還是刷公交租單車,二維碼儼然成為連接線上與線下的窗口,越來越多人選擇使用支付寶在線下進行支付。


肉眼識別二維碼?你也可以


此外,支付寶還賦予了掃碼支付額外的意義——他們在內蒙古阿拉善盟包了六塊地,只要有足夠的掃碼支付行為來支持低碳,螞蟻森林裡的樹苗長成之後,支付寶就會到那真的種下一棵樹。


2015年的春節,一波春晚集五福活動讓更多人開始拿起手機掃碼,而根據中國互聯網絡信息中心的數據,截止去年6月,中國使用網上支付的用戶規模達到4.55億。


所以剩下的8.45億,便捷、迅速、安全——還在等什麼?