
Code 39 Barcode - Complete Specification & Guide
Code 39 remains one of the most widely implemented barcode symbologies in non-retail industries because it’s discrete, self-checking, and doesn’t require licensing fees. Developed by Intermec in 1974, this alphanumeric symbology encodes 43 characters using nine elements per character — three wide bars, three wide spaces, and three narrow elements — making it simple to implement and tolerant of low-quality printing.
What is Code 39 Discrete Barcode Symbology
Code 39 is a variable-length, discrete symbology where each character stands alone, separated by an intercharacter gap. Unlike continuous symbologies that share bars between adjacent characters, Code 39 prints each character as a complete unit — five bars and four spaces — followed by a narrow gap before the next character begins.
The term “discrete” means you can read individual characters independently. If part of the barcode gets damaged, adjacent characters often remain scannable. I’ve seen warehouse environments where Code 39 labels survived months of abrasion and oil exposure while still scanning correctly — something that would destroy most continuous symbologies.
Each Code 39 character consists of nine elements: five bars (the dark vertical lines) and four spaces (the light gaps between bars). Of these nine elements, exactly three are wide and six are narrow. The ratio between wide and narrow elements typically ranges from 2:1 to 3:1, though 3:1 provides better read reliability. This fixed pattern creates the self-checking property — if the element count is wrong, the character is invalid.
The symbology earned its name from the original design where three of nine elements were wide. Modern specifications define it more precisely in ISO/IEC 16388, which standardizes the encoding rules, dimensional tolerances, and print quality requirements.
Character Encoding and Structure
Code 39 encodes 43 characters: digits 0-9, uppercase letters A-Z, and seven special characters (space, -, ., $, /, +, %). The asterisk (*) serves exclusively as the start/stop delimiter — it never appears in the data content itself.
Here’s how the encoding works: each character translates to a specific pattern of wide and narrow bars and spaces. Take the digit “1” — it encodes as wide-narrow-narrow-narrow-wide-narrow-narrow-narrow-wide (bars and spaces alternating). The letter “A” uses wide-narrow-narrow-wide-narrow-narrow-narrow-narrow-wide. These patterns are mutually exclusive; no two characters share the same element sequence.
A complete Code 39 barcode looks like this:
* [START] + DATA CHARACTERS + OPTIONAL CHECK DIGIT + * [STOP]
The start and stop characters are identical asterisks, which tells the scanner where the barcode begins and ends regardless of scan direction. Code 39 is bidirectionally readable — scan left-to-right or right-to-left, and the decoder handles the reversal automatically.
The optional modulo-43 check digit adds error detection capability. Calculate it by summing the character values (where 0=0, 9=9, A=10, Z=35, etc.), taking modulo 43, then appending the corresponding character. Many industrial applications skip the check digit since Code 39’s structure already provides self-checking at the character level. Government and military implementations often require it — the LOGMARS standard used by the U.S. Department of Defense mandates check digits for all barcodes.
Gap Spacing and Encoding Rules
The intercharacter gap separates adjacent characters and must be at least one narrow element width — the same width as a narrow bar or space within a character. This gap is crucial because it tells the decoder where one character ends and the next begins.
Unlike continuous symbologies such as Code 128 where bars are shared between characters, Code 39 requires explicit separation. The gap doesn’t encode data; it’s structural whitespace. Most implementations use a gap equal to one narrow element width, though the specification allows wider gaps if needed for printing constraints.
The quiet zone — blank space before the start character and after the stop character — must be at least 10 times the narrow element width. This quiet zone lets the scanner establish a baseline reading before hitting the first bar and prevents adjacent labels from interfering with the decode.
Width ratios matter significantly. While 2:1 (wide element twice the narrow element width) is theoretically acceptable, 3:1 delivers better real-world performance. At 2:1, a 10% printing variation can make a wide element look narrow or vice versa. At 3:1, you have more tolerance for ink spread, printing variations, or partial damage.
The narrow element width — called X-dimension — determines the overall barcode size. ISO/IEC 16388 recommends a minimum X-dimension of 0.191mm (7.5 mils) for high-quality printing. Industrial applications often use 0.330mm (13 mils) or larger for labels that will be scanned from greater distances or in less-than-ideal conditions.
Calculate total barcode width: (narrow element count × X) + (wide element count × X × ratio) + (character count × gap width) + (2 × quiet zone). For a 10-character barcode at X=0.33mm and 3:1 ratio: approximately 165mm including quiet zones.
Applications and Use Cases
Code 39 dominates three sectors: automotive, healthcare, and government/military.
Automotive assembly lines use Code 39 to track parts through manufacturing. Every component — engine blocks, transmissions, wire harnesses — gets a Code 39 label at receiving. Unlike UPC codes that require manufacturer registration, Code 39 lets companies create their own identifiers without coordination with external authorities. A Toyota plant in Kentucky might encode part numbers like “TRANS-42-A89” directly, no translation needed.
Healthcare relies on Code 39 for specimen tracking. Lab test tubes get Code 39 labels linking the sample to patient records. The alphanumeric capability means you can encode patient ID, test type, and collection time in one barcode. Blood banks use Code 39 extensively — every unit of donated blood carries a Code 39 identifier from collection through transfusion. During peak flu season, a typical hospital lab processes 2,000+ specimens daily, and Code 39 makes that volume manageable without manual data entry errors.
The U.S. Department of Defense mandated LOGMARS (Logistics Applications of Automated Marking and Reading Symbols) in 1981, which specified Code 39 as the standard for military logistics. Every piece of equipment, from ammunition crates to vehicle parts, requires Code 39 marking. The system worked so well that it’s still in use today, though newer applications are migrating to 2D symbologies for higher data density.
Code 39 also appears on driver’s licenses in many U.S. states — the barcode on the back typically uses PDF417, but older licenses used Code 39 to encode the license number and basic demographics.
Where Code 39 falls short: retail point-of-sale (UPC/EAN dominate), high-density applications (Code 128 packs more data in less space), and situations requiring lowercase letters or extensive special characters (Code 39 Full ASCII exists but doubles the barcode length).
Implementation Examples and Test Cases
Print a valid Code 39 barcode for “TEST123”:
*TEST123* (start and stop characters included)
The encoded pattern breaks down character by character, each with nine elements. Most barcode font generators handle this automatically, but understanding the structure helps when debugging print quality issues.
Test Case 1: Basic Validation
Data: ABC
Expected: Three characters between start/stop delimiters
Verification: Scan should return “ABC” without the asterisks
Test Case 2: Check Digit Calculation
Data: 12345
Character values: 1+2+3+4+5 = 15
Modulo 43: 15 % 43 = 15 (character ‘F’)
Encoded: *12345F*
Test Case 3: Wide/Narrow Ratio Testing
Print the same data at 2:1, 2.5:1, and 3:1 ratios. Test scanning distance and reliability under different lighting conditions. In my testing, 3:1 provides roughly 40% improvement in first-read rate compared to 2:1 when labels are scanned from more than 12 inches away.
Common Implementation Mistakes:
Forgetting quiet zones causes the most scan failures. Print a barcode flush against the label edge, and you’ll see 30-50% read rate drops. Always allocate quiet zones — 10X minimum, 12X for reliability.
Mixing narrow element widths within a single barcode creates decode errors. If your X-dimension varies due to inconsistent printing pressure or worn print heads, characters become unreadable. Regular printer maintenance matters more than expensive scanning equipment.
Using Code 39 for long data strings creates unnecessarily large labels. Encoding a 20-character serial number in Code 39 produces a barcode roughly twice the length of the equivalent Code 128 barcode. Know when to switch symbologies based on data density requirements.
The U.S. Department of Defense LOGMARS specification requires specific implementation parameters: 0.015 inch (0.381mm) narrow element width, 3:1 wide-to-narrow ratio, and mandatory check digit. Any supplier wanting to do business with the military needs to match these specifications exactly — close enough doesn’t work when automated systems reject non-compliant barcodes.
Frequently Asked Questions
Q: Can Code 39 encode lowercase letters?
No, standard Code 39 only encodes uppercase A-Z. Code 39 Extended (also called Full ASCII Code 39) encodes all 128 ASCII characters by using two-character combinations — a shift character followed by a standard Code 39 character. For example, lowercase ‘a’ encodes as ‘+A’. This doubles the barcode length for lowercase text, which is why most implementations stick with uppercase and avoid Extended unless absolutely necessary.
Q: What’s the maximum length for a Code 39 barcode?
There’s no theoretical limit, but practical considerations apply. Each character adds approximately 15X to the barcode length (assuming 3:1 ratio and standard gaps). Most label printers handle 4-inch wide labels comfortably, which accommodates roughly 15-20 characters at 0.33mm X-dimension. Beyond 20 characters, you’re either shrinking the X-dimension (reducing scan range) or using larger labels. If you need more than 25 characters, seriously consider Code 128 instead.
Q: Why do some Code 39 barcodes have a check digit and others don’t?
The check digit is optional according to ISO/IEC 16388 because Code 39’s structure provides character-level error detection — invalid bar/space patterns simply won’t decode. However, the check digit catches substitution errors where one valid character is misread as another valid character. Military and healthcare applications require check digits because the cost of a wrong read (shipping equipment to the wrong location, mixing up patient specimens) exceeds the minor inconvenience of calculating and printing an extra character. Commercial inventory applications often skip it.