2021SC@SDUSC Zxing open source code zxing code analysis -- one dimensional code

2021SC@SDUSC

This blog mainly introduces one-dimensional code.

Code 39

Code39 is a kind of bar code, also known as 3 of 9 code, USD-3 or LOGMARS. It is widely used because of its simple preparation, the ability to encode data of any length, wide range of equipment support and other characteristics.

characteristic:
1. It can encode data of any length. Its limitation lies in the length of printed matter and the identification range of bar code reader.
2. Support a wide range of devices. At present, almost all bar code reading devices can read Code39, and so can printers.
3. The preparation is simple. Simple development technology can quickly generate the corresponding encoded image.
4. Generally, Code39 code consists of 9 elements, including 5 lines and 4 gaps separating them. Lines and gaps can be divided into widths, and there are only three lines or gaps that are a certain proportion wider than other elements. 39 yards hence the name.

Coding rules:
1. Every five lines represent one character;
2. The thick line represents 1 and the thin line represents 0;
3. The gap between lines is 1 if it is wide and 0 if it is narrow;
4. Five lines plus four gaps between them are nine bit binary code, and three of the nine bits must be 1, so it is called 39 code;
5. The beginning and end of the barcode are marked with a * at the beginning and end.

Introduction to use:
Code 39 only accepts the following 43 valid input characters:
26 capital letters (A - Z), ten numbers (0 - 9), connecting sign (-), period (.), space, dollar sign ($), diagonal (/), plus sign (+) and percent sign (%).
The rest of the input will be ignored.
Code39 usually does not need a check code. However, for applications requiring high accuracy, a check code needs to be added after the code39 bar code.
Because two characters can be combined to express the third character In this way, the entire ASCII table can be represented by Code39 barcode This produces a Code 39 full ASCII font

  public boolean[] encode(String contents) {
    int length = contents.length();
    if (length > 80) {
      throw new IllegalArgumentException(
          "Requested contents should be less than 80 digits long, but got " + length);
    }

    for (int i = 0; i < length; i++) {
      int indexInString = Code39Reader.ALPHABET_STRING.indexOf(contents.charAt(i));
      if (indexInString < 0) {
        contents = tryToConvertToExtendedMode(contents);
        length = contents.length();
        if (length > 80) {
          throw new IllegalArgumentException(
              "Requested contents should be less than 80 digits long, but got " + length + " (extended full ASCII mode)");
        }
        break;
      }
    }

Code 93

Code 93 barcode is newer, safer and more compact than Code 39 barcode, and can read letters and numbers. It is used in the military and automotive fields. It is also used by Canada Post to encode special delivery information.

Specification: Code 93 is similar to Code 39. Its start and end characters cannot be represented by conventional ASCII characters, and are usually specified as "*". The start character is followed by encoded data. Like Code 39, each letter is represented by a numeric value. The data is followed by a two character check code to ensure accuracy when entering the code manually. These two characters are called "Modulo-47 checker C" and "Modulo-47 checker K". The combination of specific numbers in the code generates a remainder, and the corresponding letter or number becomes the checksum C or K. The check code is followed by a termination character, followed by a termination stripe, indicating the end of the bar code.

Advantages: Code 93 bar code is smaller and more efficient than Code 39, and has greater data redundancy and higher security. It also includes five special characters that are not in Code 39.

Disadvantages: unlike Code 39, Code 93 is not a self-test code, so a check bit is required.

  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]);
    }

    //Add two checksums
    int check1 = computeChecksumIndex(contents, 20);
    pos += appendPattern(result, pos, Code93Reader.CHARACTER_ENCODINGS[check1]);

    //Append to reflect the first checksum added
    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 code is a bar code system widely used in enterprise internal management, production process and logistics control system. Because of its excellent characteristics, CODE128 code is widely used in the design of management information system. CODE128 code is one of the most widely used bar code systems.

CODE128 code is a high-density bar code introduced in 1981. CODE128 code can represent 128 characters from ASCII 0 to ASCII 127, so it is called 128 code. It contains numbers, letters, and symbolic characters.

characteristic:
● it can represent high-density data and strings;
● each character is composed of 3 bars, 3 blanks and 11 units, and the string can be of variable length;
● check code is included in the symbol;
● there are three different versions: A (numbers, capital letters, control characters), B (numbers, large and small letters, characters) and C (double digits)
CODE128A: standard numbers and uppercase letters, control characters, special characters
CODE128B: standard numbers and uppercase letters, lowercase letters, special characters
CODE128C:[00]-[99], a total of 100 pairs
● 128 characters can be used in three string sets A, B or C respectively.

Composition:
A Code 128 barcode consists of six parts.
1. Blank area
2. Start tag
3. Data area
4. Check character
5. Terminator
6. Blank area
Code 128 bar code specifies that three bars and three blanks (six cells in total) separated from each other represent a character. Each character starts with a bar and ends with a blank. In bar code font, the last bar is usually combined with the terminator to form a wider terminator.

Code 128 has many similarities with Code 39, which are widely used in enterprise internal management, production process and logistics control system. The difference is that code 128 can represent more characters than Code 39, and the coding density per unit length is higher. When the Code 39 code cannot be contained in the unit length or the coded characters exceed the limit of Code 39, code 128 can be selected for coding. Therefore, code 128 is more flexible than Code 39.

Because CODE128 code can represent more comprehensive characters (numbers, letters and symbols), the length of characters that can be accommodated in bar codes of the same length is longer (high density), and the bar code length has no obvious sensitivity to the string length, CODE128 code is the most widely used bar code system in the enterprise internal management system.

  protected boolean[] encode(String contents, Map<EncodeHintType,?> hints) {
    int length = contents.length();
    // Check length
    if (length < 1 || length > 80) {
      throw new IllegalArgumentException(
          "Contents length should be between 1 and 80 characters, but got " + length);
    }

    // Check the mandatory code set prompt.
    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

CodeBar Code: also known as "code for blood bank", it can represent numbers 0-9, characters $, +, -, and four characters a, b, c and d that can only be used as start and end characters. The blank area is 10 times wider than the narrow bar. It is a discontinuous bar code. Each character is represented as 4 bars and 3 spaces. The bar code length is variable and there is no check digit. It is mainly used for blood donor management and blood bank management in blood stations, It can also be used for material management, library and airport package delivery.

  public boolean[] encode(String contents) {

    if (contents.length() < 2) {
      // Cannot have start / end protection, so add default protection temporarily
      contents = DEFAULT_GUARD + contents + DEFAULT_GUARD;
    } else {
      // Verify the input and calculate the decoding length.
      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);
        }
        // Has a valid start / end
      } else if (startsAlt) {
        if (!endsAlt) {
          throw new IllegalArgumentException("Invalid start/end guards: " + contents);
        }
        // Has a valid start / end
      } else {
        // It didn't start with guard
        if (endsNormal || endsAlt) {
          throw new IllegalArgumentException("Invalid start/end guards: " + contents);
        }
        // Otherwise, it will not end with guard, so add a default value
        contents = DEFAULT_GUARD + contents + DEFAULT_GUARD;
      }
    }

    // The start character and end character are decoded into 10 lengths respectively.
    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) + '\'');
      }
    }
    // Place a space between each character.
    resultLength += contents.length() - 1;
  }

ITF

ITF bar code, also known as cross 25 bar code, is mainly used for transportation and packaging. It is a bar code that should be selected when EAN-13 and UPC-A bar codes are not allowed to be printed due to poor printing conditions.

ITF barcode is another form of barcode different from EAN and UPC barcode. ITF-14 bar code composed of 14 digit characters is mainly used on commodity transportation packaging.

ITF bar code is a continuous, fixed length, two-way bar code with self verification function, and both bars and spaces represent information. The composition of bar code character set and bar code characters of ITF-14 bar code is the same as that of interleaved 25 code. It consists of rectangular protective frame, left blank area, bar code characters and right blank area

  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;
  }

reference material

CODE39
CODE 93 barcode
code128
ITF barcode

Keywords: Java

Added by avillanu on Tue, 28 Dec 2021 14:29:31 +0200