條形碼(barcode),也能夠叫作一維碼,在生活中普遍存在,包括常見的UPC、EAN、ISBN等等。
你看的每本書、喝的每瓶飲料、買的每件商品,基本均可以看到它們的身影。php
UPC(universal product code,通用產品代碼,一般指UPC-A) 是最先投入使用的條形碼,在美國、加拿大等歐美國家使用普遍。
儘管UPC很簡單,但倒是實現零售業結算和庫存管理自動化的基礎。
本文就從UPC着手講解條形碼是如何工做的,下文中的UPC的示例摘錄自《編碼:隱匿在計算機軟硬件背後的語言》。git
一般狀況下,UPC由30條不一樣寬度的垂直黑色條紋組成,條紋間由不一樣寬度的空白間隙分割開。
聰明的你必定想到了,這些條紋的含義就是條形碼下方的數字,組成了該商品特有的編號。
只不過,下方的數字是方便人閱讀,而條形碼是方便計算機「閱讀」。數組
例如,下圖是美國Campbell公司10盎司的罐裝雞汁麪包裝上的UPC:app
你會發現,黑色條紋粗細不均,空白間隙也是粗細不均的。
事實上,黑色條紋有四種不一樣的寬度,較寬的條的寬度是最細條的寬度的兩倍、三倍或者四倍。空白間隙亦然。編碼
UPC其實是一系列的比特,若是將一個基本單位的黑色條紋當作二進制的1
,將一個基本單位的空白間隙當作0
,就能夠露出其「廬山真面目」:spa
當計算機自左向右進行掃描時,它給遇到的第一個基本單位的黑條紋分配一個值爲1的比特值,隨後的空白間隙爲0,如此下去,直到最後一個黑色條紋爲止。一共會有95個比特,組成了一個UPC。對這95個比特進行分組:設計
起初的3個比特一般是101
,稱爲左邊護線,最右邊的3個比特也是101
,爲右邊護線,它們的做用是幫助計算機掃描儀定位。
緊挨着左邊護線,以7個比特爲一組,連續6組,爲左邊的數字;7個比特爲一組,每一組表明着數字0~9中的一個數字。
接着中間是5個比特的中間護線,固定爲01010
。這是一種內置式的檢錯碼。若是掃描儀在應當找到中間護線的地方沒有找到它,掃描儀就認爲這不是一個UPC,以此防止錯誤或竄改。
接下來的右邊的數字跟左邊數字同樣,7個比特一組,共6組。3d
有意思的是,7個比特組成一組,才表明了10個數字。照理來講,2的7次方,共128種組合,表明10個數字綽綽有餘。
這是由於,僅有少數組合的比特值,纔是有意義的。並且,左邊的數字和右邊的數字,組合還稍有差別。
映射關係以下表:code
數字 | 左邊的編碼 | 右邊的編碼 |
---|---|---|
0 | 0001101 | 1110010 |
1 | 0011001 | 1100110 |
2 | 0010011 | 1101100 |
3 | 0111101 | 1000010 |
4 | 0100011 | 1011100 |
5 | 0110001 | 1001110 |
6 | 0101111 | 1010000 |
7 | 0111011 | 1000100 |
8 | 0110111 | 1001000 |
9 | 0001011 | 1110100 |
左邊的編碼都以0開頭,以1結尾,且1的個數都是「奇數」。
右邊的編碼都以1開頭,以0結尾,且1的個數都是「偶數」。
右邊的編碼是左邊編碼的補碼:凡是1的地方都換成0,凡是0的地方都換成1。
這不是偶然,而是故意爲之。如此設計,掃描儀即便從右往左邊掃描,它也知道該如何處理。blog
另外咱們還需注意到,每一個代碼都僅有兩組連續的值爲1的比特位,這就意味着每一個數字對應着條形碼中的兩個豎條。
如此設計還提供了一種用於檢測差錯和數據一致性的機制,叫作奇偶校驗。
若是一組比特位中含有奇數個1,就稱之爲奇校驗;若是含有偶數個1,則爲偶校驗。
進行解碼時,若是發現左邊的編碼中出現偶數個1,則必定有錯。反之亦然。這提供了一種很強的容錯性,在生產中意義非凡。
如此一來,30條豎條(左邊護線2條豎線,右邊護線2條豎線,中間護線2條豎線,左右數字各12條豎線),最終對應成了12個數字:
0 51000 01251 7
在UPC中,第一個數字(這裏是0)被稱爲數字系統字符,不一樣數字表明不一樣大類的貨物。
緊接着的5個數字是製造商代碼。在上例中,51000
是Campbell公司的代碼。該公司產生的產品都是該代號,須要公司去申請。
再後面的5個數字(01251
)是該公司的某種產品的具體編號,公司自行分配。
最後的數字(這裏是7)稱做模校驗字符,這個字符提供了另一種錯誤檢驗。
最後一位的模校驗字符的計算方法以下。假設前11位數字分別用A-K符號代替:
A BCDEF GHIJK
經過公式:
3 x (A + C + E + G + I + K) + (B + D + F + H + J)
會獲得一個數字T
,而後對該數字T
,從緊挨它並大於等於它的一個10的整倍數中減去它,其結果稱爲模校驗字符。
在上例中,有:
3 × (0 + 1 + 0 + 0 + 2 + 1) + (5 + 0 + 0 + 1 + 5) = 3 × 4 + 11 = 23
緊挨着23並大於等於它的,仍是10的整倍數,就是30, 因此最後一位數字就是30-23 = 7
。
這就是印在外包裝上並以UPC形式編碼的模校驗字符,這是一種冗餘措施。
若是掃描儀計算出來的模校驗結果和UPC中編碼中的校驗字不一致,則計算機就不能將這個UPC做爲一個有效值接收。
能夠看到,簡簡單單的UPC的設計中,至少就包含了三種校驗和容錯機制,設計上煞費苦心:
在維基百科上有證實: UPC能夠檢測出100%的單數字錯誤,能夠檢測出90%的數字換位錯誤。
UPC-A(上面所講的UPC都是指UPC-A)有多種變種,其中UPC-E
和EAN-13
比較經常使用。
UPC-E是UPC-A(12位數字)的6位數字的縮短版,因爲在我國不常見,這裏再也不介紹。重點介紹EAN-13。
EAN-13是UPC-A的超集,能夠在UPC-A的首位加入一位數字0獲得。EAN-13兼容UPC-A,而且將範圍擴充爲原來的10倍。從EAN-13的前三位數字,還能夠看出生產該商品的公司所屬國。
EAN(European Article Number,歐洲商品條碼)依照結構能夠分爲EAN-13和EAN-8,但咱們常說的EAN通常特指EAN-13,而EAN-8是EAN-13的8位數字縮短版。
EAN-13的編碼內容,由四個部分組成:
有了UPC的基礎,再來說EAN-13就簡單多了。
還記得講UPC的時候,分了左邊的編碼和右邊的編碼吧。咱們將左邊的編碼稱爲L-code,右邊的編碼稱爲R-code。如今加入一列: G-code。
數字 | L-code | G-code | R-code |
---|---|---|---|
0 | 0001101 | 0100111 | 1110010 |
1 | 0011001 | 0110011 | 1100110 |
2 | 0010011 | 0011011 | 1101100 |
3 | 0111101 | 0100001 | 1000010 |
4 | 0100011 | 0011101 | 1011100 |
5 | 0110001 | 0111001 | 1001110 |
6 | 0101111 | 0000101 | 1010000 |
7 | 0111011 | 0010001 | 1000100 |
8 | 0110111 | 0001001 | 1001000 |
9 | 0001011 | 0010111 | 1110100 |
當第一位數字(導入位)不一樣時,左邊的編碼稍微調整,右邊的編碼保持不變(掃描儀依然能夠判斷是從左到右仍是相反方向)。
使用L表示採用L-code的編碼,R表示採用R-code的編碼,G表示G-code的編碼。
第一位數字 | 左邊的6位數字編碼 | 右邊的6位數字編碼 |
---|---|---|
0 | LLLLLL | RRRRRR |
1 | LLGLGG | RRRRRR |
2 | LLGGLG | RRRRRR |
3 | LLGGGL | RRRRRR |
4 | LGLLGG | RRRRRR |
5 | LGGLLG | RRRRRR |
6 | LGGGLL | RRRRRR |
7 | LGLGLG | RRRRRR |
8 | LGLGGL | RRRRRR |
9 | LGGLGL | RRRRRR |
根據映射表,以第一位的導入位爲1爲例,LLGLGG
表示,左邊的6位數字中,一、二、4採用L-code編碼,三、五、6採用G-code編碼。
根據該對照表,從左邊的6位數字編碼,就能夠反推出第一位數字是什麼,這就是爲何第一位的導入位能夠不計入條形碼的一部分。
從第一位的導入位,也能夠推出左邊的6位數字該分別採用哪一種編碼。
檢查碼的計算在UPC的基礎上也很好理解。UPC的部分提到,假設前11位數字分別用A-K符號代替,如今用N表示導入位:
N A BCDEF GHIJK
公式擴展爲:
3 x (A + C + E + G + I + K) + (N + B + D + F + H + J)
因爲UPC中,N始終爲0,所以完美兼容。
舉個例子:某條形碼爲:977167121601X(X爲校驗碼),計算出X。
能夠看出,當導入位 = 0
時(等同UPC),無論編碼仍是檢查碼,EAN-13徹底兼容UPC,條形碼不須要更改。
前三位數字 | 國家或地區 |
---|---|
690~699 | 中國 |
471 | 中國臺灣 |
489 | 中國香港 |
958 | 中國澳門 |
450~459 490~499 | 日本 |
880 | 韓國 |
885 | 泰國 |
500~509 | 英國 |
000~019 030~039 060~139 | 美國 |
300~379 | 法國 |
400~440 | 德國 |
978~979 | 圖書ISBN |
977 | 期刊ISSN |
ISBN(International Standard Book Number,國際標準書號)是非期刊書籍上的條形碼,其實只是EAN-13的子集(只討論現使用的ISBN-13)。前三位在978~979
範圍內。
一個ISBN有一個或一份相應的出版物與之對應。一本書的每一版或其餘的變化,可以申請到一個新的ISBN。
新版本若是在原來舊版的基礎上沒有內容上太大的變更,在出版時不會獲得新的ISBN。
當一本書同時有平裝本與精裝本出版時,平裝本的國際標準書號不得用於精裝本,反之亦然。
ISBN的編碼由五個部位組成,且每部位是不定長的,有時候會使用-
符號進行分割方便閱讀:
9
,前三位目前的範圍是978~979)