DacoTaco / BarcodeParserBuilder

BarcodeParserBuilder is a .Net ( standard 2.0 & 2.1 ) nuget package to help parse & build barcode strings
https://www.nuget.org/packages/BarcodeParserBuilder
GNU Lesser General Public License v2.1
11 stars 4 forks source link

Use symbology prefixes for all barcodes #6

Closed neemevool closed 1 year ago

neemevool commented 1 year ago

I see that for GS1-128 the symbology prefix ]C1 is used to recognize the barcode. Same is not used for other types. Could it be possible to use prefixes which scanner provides, for all barcodes? Currently it is kind of inconsistent

DacoTaco commented 1 year ago

hi, thanks for this report!

it is indeed better to have all barcode parsers be able to handle their prefixes, but i do not know the prefixes besides the GS1/EAN prefix.

can you provide the value's for the other barcodes and an example (to use in the unit tests)

neemevool commented 1 year ago

Different scanners are able to use different prefixes, some of them are legacy like Sunmi ID etc. I think most reasonable is to use so-called AIM ID-s, formerly defined by AIM, now ISO/IEC standard. Article on the Zebra homepage: https://supportcommunity.zebra.com/s/article/What-is-AIM-identifier-for-Barcode?language=en_US

One good overwiew: https://www.gs1.org/sites/default/files/eu2018-574requireddatacapturespecifications.pdf

Some background is on the: https://barcodeguide.seagullscientific.com/content/AIM.htm More background: https://www.aimglobal.org/

Of course, usage of the prefix should be optional in the parser. Barcode scanner may not support it (although, I havent seen any serious one which does not implement any ID-s). But if it is present, then it would make identification times faster, because there is no need to iterate over all parsers.

One thing more. By the standard the ID is not part of the barcode itself. And it is possible to configure the scanner to send some prefix and suffix also with the barcode. For example, scanner can be configured to send # in the beginning and | at the end. In that case the full read from the scanner would look for EAN-13: ]E0#1234567890128|. But I guess that should not be the concern for the library. The library should not care about prefix/suffix and expected input could be ]E01234567890128

Why Im talking about these prefixes/suffixes? In web applications it is not possible to read the scanner directly (browser cannot access the hardware) and scanners have to be configured to send barcodes as keypresses. I have developed a WASM application for example which uses barcode scanners like that. And then I need to use some symbols to distinguish regular keyboard input from the input which is sent by the scanner as keypresses.

But when I use your parser, then I remove these symbols myself. So your input should still be the valid read from the scanner without any extra symbols which are not part of the barcode.

DacoTaco commented 1 year ago

hm, this is interesting to say the least. i knew the ]C1 was part of the GS1-128/EAN-128 specs, hence it is implemented but i didn't know about the rest.

im reading mixed things here though. the ]C1 must be in a EAN-128 at the start of a barcode, as its specs define, but the zebra docs mention the prefix to be added by the scanner (making me believe it is a setting of the scanner?) to quote the website : The AIM Code ID is not part of a barcode. It is generated by the decoder of a scan engine to represent the barcode symbology that was scanned.

however, the GS1 specs you linked mention other prefixes that i have never seen in the wild before... :/

EDIT: just saw your edit, and yes i believe implementing the AIM specs in the generic barcodeparser could help improve its performance and accuracy and im more inclined to implement it like that if you agree to the change

neemevool commented 1 year ago

Thats why Im saying it should be optional. But usage of the scanner-provided barcode ID would be helpful. Scanner producers make thereby detection of the barcode much easier. For example here are options from Sunmi scanner settings. All well-known brands support AIM ID-s. image

DacoTaco commented 1 year ago

just throwing documentation out here, i am basing my aim identifiers on a more complete list found on honeywell's website : https://support.honeywellaidc.com/s/article/List-of-barcode-symbology-AIM-Identifiers

@neemevool, do you happen to have more test barcodes i could use in my unit tests besides the ]E01234567890128?

neemevool commented 1 year ago

There are few, which I retyped from my scanner.

]d20108430215011539112212221724022021S3736
]d2000761332612057038641725063010E1999E2<GS>3050<GS>24010208034
]d201040156309281941022200273<GS>112208011724073124005694302001
]C1011234567890123115991231

// the <GS> represents character 0x1D, which I have to encode with my scanner, otherwise it cant be transmitted as keystrokes
// So before I feed it to your library I replace it:
_rawbarcode = _rawbarcode.Replace("<GS>", $"{(char)0x1D}");

More barcodes can be generated at https://www.bcgen.com/linear-barcode-creator.html But I think you dont have actual scanner handy? If you want to test some exotic or more prefixes, you can point me images, I can read them with the scanner and send it.

DacoTaco commented 1 year ago

ye, i don't have a scanner nor barcodes handy haha.

i'll take your examples as test strings for my unit tests, thanks!

EDIT : also, are you ok with only having support for the QR, DataMatrix, Code39/Code128, Ean, MSI & aztec barcode prefixes to be supported? i see a lot of barcode types that i don't think are relevant yet, but i could be wrong?

DacoTaco commented 1 year ago

@neemevool : i have uploaded a preview version on nuget. can you verify it works as expected?

DacoTaco commented 1 year ago

@neemevool : any updates on your end?

neemevool commented 1 year ago

Sorry, did not have time so far. I will download it and test at my end coming week.

neemevool commented 1 year ago

Hello! Downloaded and built small sample console app. Looks good. I peeked into the changeset and how it is implemented. If Im correct, then when AIM prefix is given, then it does not try to guess other types except the one in the prefix. However, reflection in .NET 6 seems to be so good that differences between barcode with prefix (no guessing) and without prefix (guessing) are almost same (I did just loop of 1000). So in reality not much differences in speed. But what matters is possibility to validate the barcode with the prefix. Meaning, if the barcode claims to be GS1 by the prefix ]Q3 then when it is invalid, it should not be tried to be parsed as something else. For example, ]Q31234567890128 should not be tried as EAN13. And thats working. So looks good. Just one thing for future. I dont know if it may be the case at all. But I would add possibility for the explicit option in the constructor for example to say that I will feed the parser with AIM prefixes. Or in future with some other prefixes too? But thats not critical anymore. For me it is working fine. Really good job, thank you!

DacoTaco commented 1 year ago

alright! ill close this issue if it is correct right now. despite it maybe not being that much faster in theory, in practice it can be faster and it is more correct to cut off any barcode prefix if you can. for example a ]d3 is something a MSI barcode shouldn't bother with unless its specifically part of its barcode.

Thanks for reporting this! :)