1

I'm working on a project that requires read barcodes like GS1 128, and I want to separate them into the application identifiers (AI). I'm using a library called Bark.js.

It works fine with some barcodes, using AI like 01, 02, 15, 17, 10; but now I'm finding barcodes like:

(02) 98428844551697 (37) 0100 (3103) 022700 (15) 180205 (10) 05165

Ok, we leave out of account the parentheses, because they only appears in the human readable part.

I assume you know that some AI have variable length, in this case (37) and (10) have between 2-8 and 2-20 digits respectively. I'm ok with (10) because it is the end in almost all cases. But (37) can appears in the middle or in the end.

I've patched the Bark.js library, but I don't get this kind of control with variable length.

I'm searching for a weeks and I only find libraries to generate barcodes or read an image, but they not read the barcode and process it separating all AI.

Knowing all this, is there any other library in Javascript/Jquery or PHP to control all these cases??

PS: Sorry for my English, I'll be happy to respond to any questions.

Terry Burton
  • 2,801
  • 1
  • 29
  • 41
bey23
  • 313
  • 4
  • 16
  • 2
    Bark.js apparently has no support for non-printable FNCx codes. My understanding is that a variable length AI must end with a FNC1 code. If these codes do not appear in your input, you're kind of stuck. [This question](http://stackoverflow.com/questions/31318648/what-is-the-actual-hex-binary-value-of-the-gs1-fnc1-character) (and its accepted answer) may contain relevant information. – Arnauld Aug 05 '16 at 11:24
  • Does your input come from a real barcode reader or is it manually typed in? And most importantly: is it somehow possible to include non-printable FNCx codes in there? – Arnauld Aug 05 '16 at 12:07
  • @Arnauld I use a code bar reader, which is integrated in a tablet, to write in my input type text. Usually the barcode is not manually typed in it. And I have no idea if is possible to include FNCx codes with that. I should use other way? Thanks – bey23 Aug 05 '16 at 12:14
  • 1
    The documentation of the tablet might provide a way to output FNCx codes. If it's not possible, the best solution I can think of would be to list all possible valid decoding outcomes, given an input string and a list of AI definitions that may be encountered in it. If you're lucky, there may be only one possible result most of the time. – Arnauld Aug 05 '16 at 12:32
  • @Arnauld The tablet uses the 'BarcodScanWizard' plugin to read, and it is so simple and without documentation that is impossible to do anything with it. I will continue doing patches the Bark.js to get several cases, like you say. Thank you for your advices :) – bey23 Aug 05 '16 at 12:50

1 Answers1

1

To sum it up, it turns out that you need to decode the Application Identifiers (AI) inside a GS1 128 barcode which is missing its non-printable FNCx codes. Because some of the AIs have a variable length and should be delimited by a FNC1 code, the best you can do is guessing. (I'm not a bar code expert, so please don't hesitate to comment this answer if my analysis is incorrect.)

This leaves us with a rather interesting problem: find all possible valid decoding outcomes, given an input string and a list of AI definitions that may be encountered in it.

Below is my attempt at solving this problem.

I've included all AI codes that were originally defined in Bark.js, completed with the extra AI codes that you seem to have encountered so far (using the formats described on this page).

This algorithm takes the string '02984288445516973701003103022700151802051005165' as an input and generates the following list of solutions, in a recursive way:

Solution #1: (02)98428844551697(37)0(10)0(310)3022700(15)180205(10)05165
Solution #2: (02)98428844551697(37)0(10)03(10)302270(01)51802051005165
Solution #3: (02)98428844551697(37)0(10)03(10)3022700(15)180205(10)05165
Solution #4: (02)98428844551697(37)0(10)03(10)302270015180205(10)05165
Solution #5: (02)98428844551697(37)0(10)0310302270(01)51802051005165
Solution #6: (02)98428844551697(37)0(10)03103022700(15)180205(10)05165
Solution #7: (02)98428844551697(37)0(10)0310302270015180205(10)05165
Solution #8: (02)98428844551697(37)01(00)310302270015180205(10)05165
Solution #9: (02)98428844551697(37)0100(310)3022700(15)180205(10)05165
Solution #10: (02)98428844551697(37)01003(10)302270(01)51802051005165
Solution #11: (02)98428844551697(37)01003(10)3022700(15)180205(10)05165
Solution #12: (02)98428844551697(37)01003(10)302270015180205(10)05165

Unfortunately, that's a rather long list. The correct solution in your case appears to be #9.

var aiDef = {        // the AI data format is encoded as either:
  '00' : 18,         //  - fixed length   : N
  '01' : 14,         //  - variable length: [ MIN, MAX ] 
  '02' : 14,
  '10' : [ 1, 20 ],
  '11' : 6,
  '12' : 6,
  '13' : 6,
  '15' : 6,
  '16' : 6,
  '17' : 6,
  '310': 7,
  '37' : [ 1, 8 ]
};

function decode(str) {
  var res = [];

  recurse(str, '', res);
  return res;
}

function recurse(str, path, res) {
  // push solution path if we've successfully
  // made it to the end of the string
  if(str == '') {
    res.push(path);
    return;
  }

  var i, j, ai, code;

  // find next AI code
  for(
    i = 0, ai = void(0);
    i < str.length && (ai = aiDef[code = str.substr(0, i)]) === undefined;
    i++
  ) {}

  if(ai !== undefined) {
    // recode AI definition to unique format [ MIN, MAX ]
    ai = typeof ai == 'object' ? ai : [ ai, ai ];

    // iterate on all possible lengths and perform recursive call
    for(j = ai[0]; j <= ai[1]; j++) {
      if(i + j <= str.length) {
        recurse(str.substr(i + j), path + '(' + code + ')' + str.substr(i, j), res);
      }
    }
  }
}

var res = decode('02984288445516973701003103022700151802051005165');

res.forEach(function(r, i) {
  console.log('Solution #' + (i + 1) + ': ' + r);
});
Arnauld
  • 5,847
  • 2
  • 15
  • 32
  • @bey23 It's possible to reduce the number of solutions if we make the assumption that the same AI code cannot appears twice in the same input. Do you know if it is true? – Arnauld Aug 05 '16 at 13:54