Pharmaceutical barcode generator
The three barcodes the pharmaceutical industry uses and almost nobody else does: Laetus Pharmacode, Italy's Code 32 and Germany's PZN. Each solves a different problem, and one of them has no check digit at all, on purpose.
Pharmacode: a number in the bar widths, and nothing else
Pharmacode carries a value from 3 to 131,070 and that is the whole content model. No character set, no check digit, no start or stop pattern. The number is written in binary where a thin bar is a zero and a thick bar is a one, read from the right, which is why the symbol grows from 4 modules at the low end to 78 at the top.
The absence of a check digit looks like an oversight and is not. Pharmacode is printed on blister foil and carton flaps and read by a fixed optical head on a packaging line at speed, where the job is to confirm that the right leaflet is in the right box. The line already knows which code it expects, so the verification is a comparison rather than a self-check, and every bar spent on a check digit would be a bar that did not fit.
That has a consequence worth knowing before you use one anywhere else: a misread Pharmacode is a valid Pharmacode for a different product. If anything in your system treats every barcode as self-validating, this is the one that breaks the assumption, which makes it a useful thing to have in a test suite.
Code 32: the bars do not spell the digits
Italy's codice farmaceutico is a nine digit number, and the barcode is a Code 39 symbol. What it does not contain is those digits. The nine digit number is converted to base 32 and the six resulting characters are what the bars spell, which is why a Code 32 symbol is always 103 modules wide however large the number.
The base-32 alphabet is the ten digits plus the consonants, with A, E, I and O left out so a code cannot accidentally spell a word. U is included, which is the kind of detail worth checking rather than assuming. A reader that understands Code 32 converts the six characters back and reports the number with an A in front, so the string you see from a scanner is not the string in the symbol.
This page takes the eight digit product number and computes the ninth. Its check digit weights the positions 1 and 2 alternately from the left, folds a doubled value to its digit sum, and takes the total modulo ten directly. That last part is the trap: there is no ten-minus complement, so every implementation that assumes plain Luhn gets it wrong.
PZN: seven digits, modulo eleven, and a number that cannot exist
The German Pharmazentralnummer is seven digits and a check digit, carried by a Code 39 symbol whose first character is a hyphen. The symbol is always 142 modules. The check digit multiplies each digit by its position, one through seven, and takes the remainder modulo eleven.
Modulo eleven has eleven possible results and only ten digits to write them in, so some seven digit numbers produce a remainder of ten and simply have no valid PZN. This page refuses those rather than adjusting the number, because a PZN that cannot exist should not be drawn. Paste eight digits instead and the last is checked rather than computed, with the correct value reported if it is wrong.
How far each one is verified, which differs
Code 32 and PZN are round-tripped through zxing-cpp, an independent decoder, and required to return the exact expected string before release. For Code 32 that check is doing real work: it proves the base-32 alphabet and the check digit rule together, and it is what caught four plausible check digit rules being wrong, the best of which matched only a third of the samples.
Pharmacode cannot be checked that way, because no open decoder implements it. What it gets instead is stronger in one respect and weaker in another: every value from 3 to 131,070 is encoded and read back, so the arithmetic is proved across the symbology's entire range rather than sampled. What that cannot tell you is whether a real Laetus reader agrees with our bar widths, and this page would rather say so than imply a guarantee it does not have.
Which one you actually need
- Pharmacode for packaging-line verification, and for testing anything that assumes a barcode validates itself. It carries a number and no metadata.
- Code 32 for a product sold in Italy, where it is what appears on the box alongside the human-readable nine digit number.
- PZN for Germany and Austria. Note it is the pharmaceutical identifier, not a GTIN, so it does not replace an EAN-13 at a retail checkout.
- GS1 Data Matrix if what you need is serialization: a unique identifier, batch and expiry on a small square, which is what pharmaceutical traceability has moved to.
Questions
Why does Pharmacode have no check digit?
Because the reader already knows what it expects. Pharmacode is read by a fixed head on a packaging line comparing against the code for that batch, so verification is a comparison rather than a self-check, and the bars are better spent on the number. It does mean a misread is a valid code for something else.
What is the largest number a Pharmacode can hold?
131,070, and the smallest is 3. Both limits are enforced here rather than silently wrapping. The symbol grows with the value, from 4 modules at the bottom of the range to 78 at the top.
Why does my Code 32 scanner show a different string than I typed?
Because the symbol carries six base-32 characters rather than your digits. A reader that knows Code 32 converts them back and reports the nine digit number with an A in front. If your reader shows six letters and digits instead, it is reading the symbol as plain Code 39 and has not been told to expect Code 32.
Why was my PZN rejected?
Either the check digit you supplied disagrees with the computed one, in which case you are told what it should be, or the number's weighted sum leaves a remainder of ten modulo eleven. Modulo eleven has one more result than there are digits, so those numbers have no valid PZN and are not adjusted into one.
More barcode generators
Test barcode numbers · Free barcode generator · EAN-13 barcode generator · UPC barcode generator · Code 128 barcode generator · Code 39 barcode generator · Barcode generator · QR code generator