Search code examples
javabarcodeerror-correctionreed-solomonpdf417

pdf417 barcode creation, Reed Solomon error correction codewords disparity between python and JAVA


I created a pdf417 barcode using the Python library pdf417gen.

The barcode was a graphical representation of the string "M1LONG". The barcode has two data columns and the Reed Solomon error correction security level is set to "1". This indicates that with an input of eight data codewords, the number of error correction codewords should be four.

The Python output displays the data code words from D07 to D00 as {8, 389, 902, 11, 900, 344, 396, 900}. The python lists the error correction codewords from C03 to C00 as {718, 801, 313, 877}. Here is the Python that was used to generate all the codewords:

from builtins import range

from .data import ERROR_CORRECTION_FACTORS

def compute_error_correction_code_words(data_words, level):
    assert 0 <= level <= 8

    # Correction factors for the given level
    factors = ERROR_CORRECTION_FACTORS[level]

    # Number of EC words
    count = 2 ** (level + 1)

    # Correction code words list, prepopulated with zeros
    ec_words = [0] * count

    # Do the math
    for data_word in data_words:
        temp = (data_word + ec_words[-1]) % 929

        for x in range(count - 1, -1, -1):
            word = ec_words[x - 1] if x > 0 else 0
            ec_words[x] = (word + 929 - (temp * factors[x]) % 929) % 929

    return [929 - x if x > 0 else x for x in reversed(ec_words)]

The error correction codewords are generated using polynomials, Galois Field arithmetic and complements of modulus 929, which is the number of possible codewords for the pdf417 system. The calculations use a number of factors to simplify the process. For security level 1 the recommended number of factors is four. The factors are 522,568,723,809

http://grandzebu.net/informatique/codbar/pdf417coef.txt

The problem is this. I tried to re-create the error codewords using a JAVA pseudo code obtained from http://grandzebu.net/informatique/codbar-en/pdf417.htm

I wrote a JAVA program to try and generate the same codewords as the Python software described above, but it does not generate the same error codewords.

The JAVA programme compiles and runs, the math looks alright to my untrained eye, but the error codes produced are not the same. Here is my JAVA, The JAVA variables are termed the same as the Python to make it easier to compare the two programmes.

import java.util.Arrays;

public class reedsolomon{

    public static void main (String[] args){

        int ec_words[] = new int[4];//correction codewords array
        int temp=0;//holding variable
        int count=4; //number of error correction codewords
        int data_words[] = {8,389,902,11,900,344,396,900};// eight data codewords array D7 to D0.
        int factors[]= {522,568,723,809}; //factors or coefficients array.
        for(int i=0; i<data_words.length-1; i++) { 
            temp=(data_words[i] + ec_words[count-1])%929;
            for(int x=count-1; x>-1; x--){
                if(x==0){
                    ec_words[x] = (929-(temp*factors[x])%929)%929; //negative values in the Galois Field
                    //GF(929) are equal to the complement of itself if
                    //ec_words[x] > -929
                }
                else{
                    ec_words[x]=(ec_words[x-1]+929-(temp*factors[x])%929) %929; //negative values in the Galois Field
                    //GF(929) are equal to the complement of the
                    //remainder (ec_words[x] /929) if ec_words[x] <= -929.
                }
            }
        }
        for(int j=0; j<count; j++){
            if(ec_words[j] != 0){
                ec_words[j]=929-ec_words[j]; 
            }
        }System.out.println("Error codewords are " + Arrays.toString(ec_words));
    }
}

I would be most grateful to know what the problem is with the JAVA code that prevents it from generating the same error codewords as the python program contained in the library pdf417gen.


Solution

  • There are two problems in your code.

    1. The most important one: you're not processing all words. Your code reads:

      for(int i=0; i<data_words.length-1; i++) { 
      

      But it should read:

      for(int i=0; i < data_words.length; i++) {
      

      In your for-loop you're missing the last data word in data_words[data_words.length-1]

    2. You're not reversing the ec_words array in the Java code, like you do in python, so the outcome is in the reverse order in ec_words.

    With the first fix applied, the outcome from the Java code is:

    Error codewords are [877, 313, 801, 718]