2021SC@SDUSC Zxing开源代码(十七)Zxing代码解析——一维码
2021SC@SDUSC
目錄
- Code 39
- Code 93
- Code 128
- Codabar
- ITF
- 參考資料
前言:本篇博客主要介紹一維碼。
Code 39
Code39是條形碼的一種,也被稱為3 of 9 code、USD-3或者LOGMARS,由于編制簡單、能夠?qū)θ我忾L度的數(shù)據(jù)進(jìn)行編碼、支持設(shè)備廣泛等特性而被廣泛采用。
特點(diǎn):
1、能夠?qū)θ我忾L度的數(shù)據(jù)進(jìn)行編碼。其局限在于印刷品的長度和條碼閱讀器的識別范圍。
2、支持設(shè)備廣泛。目前幾乎所有的條形碼閱讀設(shè)備都能閱讀Code39碼,打印機(jī)也是同樣情況。
3、編制簡單。簡單的開發(fā)技術(shù)就能快速生成相應(yīng)的編碼圖像。
4、一般Code39碼由5條線和分開它們的4條縫隙共9個元素構(gòu)成。線和縫隙有寬窄之分,而且無論線還是縫隙僅有3個比其他的元素要寬一定比例。39碼因此得名。
編碼規(guī)則:
1、每五條線表示一個字符;
2、 粗線表示1,細(xì)線表示0;
3、 線條間的間隙寬的表示1,窄的表示0;
4、 五條線加上它們之間的四條間隙就是九位二進(jìn)制編碼,而且這九位中必定有三位是1,所以稱為39碼;
5、 條形碼的首尾各一個 * 標(biāo)識開始和結(jié)束。
使用介紹:
Code 39只接受如下43個有效輸入字符:
26個大寫字母(A - Z),十個數(shù)字(0 - 9),連接號(-),句號(.),空格,美圓符號($),斜扛(/),加號(+)以及百分號(%)。
其余的輸入將被忽略。
code39通常情況下不需要校驗(yàn)碼。但是對於精確度要求高的應(yīng)用,需要在code39條形碼後面增加一個校驗(yàn)碼。
由于可以合并兩個字符來表達(dá)第三個字符.這樣就可以用Code39條形碼來表示整個ASCII表.這樣就產(chǎn)生了Code 39全ASCII碼字型.
Code 93
Code 93 條碼比 Code 39 條碼更新、更安全且更緊湊,能讀取字母和數(shù)字。它用于軍事和汽車領(lǐng)域,還被加拿大郵政用來對特殊投遞信息進(jìn)行編碼。
規(guī)格:Code 93 跟 Code 39 類似,其起始符和終止符不能以常規(guī) ASCII 字符表示,通常指定為“*”。起始符后面是編碼的數(shù)據(jù)。跟 Code 39 一樣,每個字母由數(shù)值代表。數(shù)據(jù)后面是兩個字符的校驗(yàn)碼,用于在手動輸入代碼時保證準(zhǔn)確性。這兩個字符被稱為“Modulo-47 校驗(yàn)符 C”和“Modulo-47 校驗(yàn)符 K”。代碼中特定的數(shù)字組合生成一個余數(shù),對應(yīng)的字母或數(shù)字就變成了校驗(yàn)符 C 或 K。校驗(yàn)碼后面是終止符,緊接著是終止條紋,表明條碼結(jié)束。
優(yōu)勢: Code 93 條碼比 Code 39 更小巧、更高效,且擁有更大的數(shù)據(jù)冗余,具備更高的安全性。它還包括 Code 39 中沒有的 5 個特殊字符。
缺點(diǎn):不同于 Code 39,Code 93 不是自檢碼,因此需要一個校驗(yàn)位。
public boolean[] encode(String contents) {contents = convertToExtended(contents);int length = contents.length();if (length > 80) {throw new IllegalArgumentException("Requested contents should be less than 80 digits long after converting to extended encoding, but got " + length);}int codeWidth = (contents.length() + 2 + 2) * 9 + 1;boolean[] result = new boolean[codeWidth];int pos = appendPattern(result, 0, Code93Reader.ASTERISK_ENCODING);for (int i = 0; i < length; i++) {int indexInString = Code93Reader.ALPHABET_STRING.indexOf(contents.charAt(i));pos += appendPattern(result, pos, Code93Reader.CHARACTER_ENCODINGS[indexInString]);}//添加兩個校驗(yàn)和int check1 = computeChecksumIndex(contents, 20);pos += appendPattern(result, pos, Code93Reader.CHARACTER_ENCODINGS[check1]);//追加內(nèi)容以反映添加的第一個校驗(yàn)和contents += Code93Reader.ALPHABET_STRING.charAt(check1);int check2 = computeChecksumIndex(contents, 15);pos += appendPattern(result, pos, Code93Reader.CHARACTER_ENCODINGS[check2]);pos += appendPattern(result, pos, Code93Reader.ASTERISK_ENCODING);result[pos] = true;return result;}Code 128
CODE128碼是廣泛應(yīng)用在企業(yè)內(nèi)部管理、生產(chǎn)流程、物流控制系統(tǒng)方面的條碼碼制,由于其優(yōu)良的特性在管理信息系統(tǒng)的設(shè)計(jì)中被廣泛使用,CODE128碼是應(yīng)用最廣泛的條碼碼制之一。
CODE128碼是1981年引入的一種高密度條碼,CODE128 碼可表示從 ASCII 0 到ASCII 127 共128個字符,故稱128碼。其中包含了數(shù)字、字母和符號字符。
特點(diǎn):
●可表示高密度數(shù)據(jù)和字符串;
●每個字符由3個條、3個空、11個單元構(gòu)成,字符串可變長;
●符號內(nèi)含校驗(yàn)碼;
●有三種不同的版本:A(數(shù)字、大寫字母、控制字符)B(數(shù)字、大小字母、字符)C(雙位數(shù)字)
CODE128A:標(biāo)準(zhǔn)數(shù)字和大寫字母,控制符,特殊字符
CODE128B:標(biāo)準(zhǔn)數(shù)字和大寫字母,小寫字母,特殊字符
CODE128C:[00]-[99]的數(shù)字對集合,共100個
●可用128個字符分別在A、B或C三個字符串集合中。
構(gòu)成:
一個Code 128條形碼由六部分組成。
1、空白區(qū)域
2、起始標(biāo)記
3、數(shù)據(jù)區(qū)
4、校驗(yàn)符
5、終止符
6、空白區(qū)域
Code 128條碼指定相互間隔的3個條形和3個空白(共六個單元)代表一個字符,每個字符由一個條開始,以一個空結(jié)束。 在條形碼字體中,最后一個條形通常與終止符一起組合成一個更寬的終止符。
Code 128碼與Code 39碼有很多的相近性,都廣泛運(yùn)用在企業(yè)內(nèi)部管理、生產(chǎn)流程、物流控制系統(tǒng)方面。不同的在于Code 128比Code 39能表現(xiàn)更多的字符,單位長度里的編碼密度更高。當(dāng)單位長度里不能容下Code 39編碼或編碼字符超出了Code 39的限制時,就可選擇Code 128來編碼。所以Code 128比Code 39更具靈活性。
由于CODE128碼可表示較全面的字符(數(shù)字、字母和符號),在同樣長度的條碼中可容納的字符長度較長(高密度),條碼長度與字符串長度無明顯的敏感性,所以CODE128碼是企業(yè)內(nèi)部管理系統(tǒng)最為廣泛使用的條碼碼制。
protected boolean[] encode(String contents, Map<EncodeHintType,?> hints) {int length = contents.length();// 檢查長度if (length < 1 || length > 80) {throw new IllegalArgumentException("Contents length should be between 1 and 80 characters, but got " + length);}// 檢查強(qiáng)制代碼集提示。int forcedCodeSet = -1;if (hints != null && hints.containsKey(EncodeHintType.FORCE_CODE_SET)) {String codeSetHint = hints.get(EncodeHintType.FORCE_CODE_SET).toString();switch (codeSetHint) {case "A":forcedCodeSet = CODE_CODE_A;break;case "B":forcedCodeSet = CODE_CODE_B;break;case "C":forcedCodeSet = CODE_CODE_C;break;default:throw new IllegalArgumentException("Unsupported code set hint: " + codeSetHint);}}Codabar
庫德巴條形碼( Codabar):也稱“血庫用碼”,可表示數(shù)字0-9,字符$、+、-,還有只能用作起始和終止符的a、b、c、d四個字符,空白區(qū)比窄條寬10倍,非連續(xù)性條形碼,每個字符表示為4條3空,條形碼長度可變,沒有校驗(yàn)位,主要應(yīng)用于血站的獻(xiàn)血員管理和血庫管理,也可作物料管理、圖書館、機(jī)場包裹發(fā)送中。
public boolean[] encode(String contents) {if (contents.length() < 2) {// 無法有開始/結(jié)束保護(hù),因此暫時添加默認(rèn)保護(hù)contents = DEFAULT_GUARD + contents + DEFAULT_GUARD;} else {// 驗(yàn)證輸入并計(jì)算解碼長度。char firstChar = Character.toUpperCase(contents.charAt(0));char lastChar = Character.toUpperCase(contents.charAt(contents.length() - 1));boolean startsNormal = CodaBarReader.arrayContains(START_END_CHARS, firstChar);boolean endsNormal = CodaBarReader.arrayContains(START_END_CHARS, lastChar);boolean startsAlt = CodaBarReader.arrayContains(ALT_START_END_CHARS, firstChar);boolean endsAlt = CodaBarReader.arrayContains(ALT_START_END_CHARS, lastChar);if (startsNormal) {if (!endsNormal) {throw new IllegalArgumentException("Invalid start/end guards: " + contents);}// 已具有有效的開始/結(jié)束} else if (startsAlt) {if (!endsAlt) {throw new IllegalArgumentException("Invalid start/end guards: " + contents);}// 已具有有效的開始/結(jié)束} else {// 不是從guard開始的if (endsNormal || endsAlt) {throw new IllegalArgumentException("Invalid start/end guards: " + contents);}// 否則也不會以guard結(jié)尾,所以添加一個默認(rèn)值contents = DEFAULT_GUARD + contents + DEFAULT_GUARD;}}// 起始字符和結(jié)束字符分別解碼為10個長度。int resultLength = 20;for (int i = 1; i < contents.length() - 1; i++) {if (Character.isDigit(contents.charAt(i)) || contents.charAt(i) == '-' || contents.charAt(i) == '$') {resultLength += 9;} else if (CodaBarReader.arrayContains(CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED, contents.charAt(i))) {resultLength += 10;} else {throw new IllegalArgumentException("Cannot encode : '" + contents.charAt(i) + '\'');}}// 在每個字符之間放置一個空格。resultLength += contents.length() - 1;}ITF
ITF條碼,又稱交叉二五條碼,主要用于運(yùn)輸包裝,是印刷條件較差,不允許印刷EAN-13和UPC-A條碼時應(yīng)選用的一種條碼。
ITF條碼是有別于EAN、UPC條碼的另一種形式的條碼。在商品運(yùn)輸包裝上使用的主要是14位數(shù)字字符代表組成的ITF-14條碼。
ITF條碼是一種連續(xù)型、定長、具有自校驗(yàn)功能,并且條、空都表示信息的雙向條碼。ITF-14條碼的條碼字符集、條碼字符的組成與交插二五碼相同。它由矩形保護(hù)框、左側(cè)空白區(qū)、條碼字符、右側(cè)空白區(qū)組成.
public boolean[] encode(String contents) {int length = contents.length();if (length % 2 != 0) {throw new IllegalArgumentException("The length of the input should be even");}if (length > 80) {throw new IllegalArgumentException("Requested contents should be less than 80 digits long, but got " + length);}checkNumeric(contents);boolean[] result = new boolean[9 + 9 * length];int pos = appendPattern(result, 0, START_PATTERN, true);for (int i = 0; i < length; i += 2) {int one = Character.digit(contents.charAt(i), 10);int two = Character.digit(contents.charAt(i + 1), 10);int[] encoding = new int[10];for (int j = 0; j < 5; j++) {encoding[2 * j] = PATTERNS[one][j];encoding[2 * j + 1] = PATTERNS[two][j];}pos += appendPattern(result, pos, encoding, true);}appendPattern(result, pos, END_PATTERN, true);return result;}參考資料
CODE39
CODE 93 條碼
code128
ITF條碼
總結(jié)
以上是生活随笔為你收集整理的2021SC@SDUSC Zxing开源代码(十七)Zxing代码解析——一维码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美字
- 下一篇: 很遗憾,这就是现实!35岁之后软件测试工