1.起因:
1.0 在《小別科技》這個(gè)項(xiàng)目中.存在一個(gè)需求,掃描商品的條形碼,以登陸商品的入庫(kù)信息.但是在Android的有一定概率掃描出的條形碼是錯(cuò)誤的.體現(xiàn)的效果就是掃描出的條形碼指向了其他的商品.
1.1 這引起了我的思考,因?yàn)樵O(shè)備的和環(huán)境的因素導(dǎo)致掃描的結(jié)果與實(shí)際存在出入完全可以理解.但是條形碼自身難道沒(méi)有任何的糾錯(cuò)及校驗(yàn)機(jī)制嗎?
1.2 先假設(shè)條形碼本身無(wú)任何糾錯(cuò)及校驗(yàn)機(jī)制.那么假如在商場(chǎng)中有兩個(gè)條形碼很相近的物品A和B.
他們的條形碼的區(qū)別僅在于A的低3條黑線是細(xì)的,而B(niǎo)的第三條黑線是粗的.其余部分均相同.而A的價(jià)格是¥1000 B的價(jià)格是¥10.
那么我們?cè)谏坛琴?gòu)物的時(shí)候故意將A的條形碼的第三條涂粗,是否就能騙過(guò)掃碼的機(jī)器,只用付10元就能拿走A商品?
然而現(xiàn)實(shí)中在商城購(gòu)買(mǎi)東西是會(huì)遇到掃不出碼的情況,但卻從未遇到掃錯(cuò)商品的情況.-
1.3 因此在條形碼中應(yīng)該存在一種保護(hù)機(jī)制,讓掃條形碼僅有下述1,2兩種可能.
1.正確掃描出條形碼
2.掃描的結(jié)果錯(cuò)誤
3.掃描成其他商品
2.發(fā)現(xiàn)
- 2.1 這個(gè)問(wèn)題的答案在《編碼——隱匿在計(jì)算機(jī)軟硬件背后的語(yǔ)言》書(shū)中找到了答案.
-
2.2 條形碼UPC(universal product code).通常情況下是由30條不同寬度的垂直黑色條紋的集合,由不同寬度的間隔分隔開(kāi).
按區(qū)域劃分
| 左側(cè)空白區(qū) | 起始符號(hào) | 左側(cè)數(shù)據(jù)符 | 中間分隔符 | 右側(cè)數(shù)據(jù)符 | 校驗(yàn)符 | 終止符 | 右側(cè)空白區(qū) |
|---|---|---|---|---|---|---|---|
| 2豎線 | 6位數(shù)字 | 2豎線 | 5位數(shù)字 | 1位數(shù)字 | 2豎線 |
-
2.3 實(shí)驗(yàn):
下圖是我隨手找來(lái)的一包紙的UPC.
用代碼生成二維碼

-
2.4 字符編碼規(guī)則
從左向右,第2位到第7位(6個(gè)數(shù)字)為左側(cè)字符。左側(cè)字符采用兩種編碼方式:A方式或B方式,編碼表如下:
然后根據(jù)前置碼(第一位)確定這6個(gè)字符的編碼方式是A還是B。
前置碼決定的編碼方式如下表:
6931767054590的前置碼為6,查上表,左側(cè)6個(gè)數(shù)據(jù)的編碼方式為ABBBAA。
右側(cè)字符從第8個(gè)字符起到最后一位。均按照C方式編碼。 2.5 開(kāi)始轉(zhuǎn)碼
| 比特 | 含義 |
|---|---|
| 101 | 左護(hù)線 |
| 0001011 | 左字符(編碼A) 10進(jìn)制:9 |
| 0100001 | 左字符(編碼B) 10進(jìn)制:3 |
| 0110011 | 左字符(編碼B) 10進(jìn)制:1 |
| 0010001 | 左字符(編碼B) 10進(jìn)制:7 |
| 0101111 | 左字符(編碼A) 10進(jìn)制:6 |
| 0111011 | 左字符(編碼A) 10進(jìn)制:7 |
| 01010 | 中間分隔符 |
| 1110010 | 右字符(編碼C) 10進(jìn)制:0 |
| 1001110 | 右字符(編碼C) 10進(jìn)制:5 |
| 1011100 | 右字符(編碼C) 10進(jìn)制:4 |
| 1001110 | 右字符(編碼C) 10進(jìn)制:5 |
| 1110100 | 右字符(編碼C) 10進(jìn)制:9 |
| 1110010 | 右字符(編碼C) 10進(jìn)制:0 |
| 101 | 右護(hù)線 |
所得結(jié)果為:931767054590 與條形碼下的數(shù)字相同
3.校驗(yàn):
- 3.1 奇偶校驗(yàn)
A子集下1的個(gè)數(shù)總為奇數(shù),BC子集下1的個(gè)數(shù)總為偶數(shù).
因此若在掃描的連奇偶校驗(yàn)都通不過(guò)則立即視為無(wú)效條形碼. - 3.2 校驗(yàn)碼:校驗(yàn)碼為條形碼10進(jìn)制表達(dá)式下的最后一位數(shù)如6931767054590的校驗(yàn)碼即為0;
1.將除最后一位的所有奇數(shù)位相加.
6 + 3 + 7 + 7 + 5 + 5 = 33
2.將除最后一位的所有偶數(shù)數(shù)位相加并x3.
(9 + 1 + 6 + 0 + 4 + 9) * 3 = 87
3.將上面兩數(shù)相加并用10 減去相加數(shù)的個(gè)位數(shù)
校驗(yàn)碼 = 10 - ((33 + 87) % 10) = 10 即為0;
因此校驗(yàn)碼與結(jié)果相同 成功通過(guò)校驗(yàn).



