Code 39 Barcode Explained

Code 39 Example

Originally developed in the 1970s, Code 39 encodes numbers, capital letters (A-Z) and some special characters. By using combinations of two symbols the full ASCII character set can be encoded including special characters like currency symbols. If those combinations of symbols are used the code is referred to as Code 39 Extended. The "39" in the symbology's name does not refer to the size of the encodable character set, this is a common misconception. Instead, it's short for "three of nine", from the fact that an individual symbol has nine elements (bars and spaces), three of which are wide. This naming scheme is derived from Code 2-of-5 which has five elements, two of which are wide.

Code 39 is mainly used for warehousing, in Germany and other countries it is also used for pharmaceutical products.

Code 39 at a Glance

  • Type: Linear barcode symbology
  • Applications: Warehousing, pharma
  • Character set: A-Z, 0-9, '-', '.', ' ', '$', '/', '+', '%'
  • Modes: Standard, Extended (full ASCII character set)
  • Check digit: Modulo 43 (not mandatory)
  • Generators: Stand-alone, barcode fonts, barcode extensions
  • Scanning: CCD / Laser scanners, imagers, scanner apps
  • Printing: Thermal direct, thermal transfer, laser, inkjet, dot-matrix

Code 39 Sizes, Low Density vs High Density

Code 39 has very lenient specifications and can be created with module widths ranging from 0.1 to over 5mm, same goes for the height of the code. We recommend a module width of 0.5mm and a module height of 20mm for most applications.

Likewise, the ratio of wide to narrow bars can be anywhere between 2.0 and 3.0. Smaller ratios will increase the density of the code (making it smaller for given data) but can make scanning the code more challenging.

A code with a ratio of 2.0 ("High Density" or "HD"):

Code 39 Example High Density

A code with a ratio of 2.5 ("Medium Density"), best choice for most applications:

Code 39 Example Medium Density

A code with a ratio of 3.0 ("Low Density" or "LD"):

Code 39 Example Low Density

Code 39 / Code 39 Extended Bit Pattern

The Code 39 bit pattern (JavaScript array syntax). First item is the character, followed by nine elements for bars and spaces; '0' is a narrow element, '1' is a wide element. The bit pattern of the start / stop character is at the '*' slot.

const c39_bp =
[
  ['0','0','0','0','1','1','0','1','0','0'],
  ['1','1','0','0','1','0','0','0','0','1'],
  ['2','0','0','1','1','0','0','0','0','1'],
  ['3','1','0','1','1','0','0','0','0','0'],
  ['4','0','0','0','1','1','0','0','0','1'],
  ['5','1','0','0','1','1','0','0','0','0'],
  ['6','0','0','1','1','1','0','0','0','0'],
  ['7','0','0','0','1','0','0','1','0','1'],
  ['8','1','0','0','1','0','0','1','0','0'],
  ['9','0','0','1','1','0','0','1','0','0'],
  ['A','1','0','0','0','0','1','0','0','1'],
  ['B','0','0','1','0','0','1','0','0','1'],
  ['C','1','0','1','0','0','1','0','0','0'],
  ['D','0','0','0','0','1','1','0','0','1'],
  ['E','1','0','0','0','1','1','0','0','0'],
  ['F','0','0','1','0','1','1','0','0','0'],
  ['G','0','0','0','0','0','1','1','0','1'],
  ['H','1','0','0','0','0','1','1','0','0'],
  ['I','0','0','1','0','0','1','1','0','0'],
  ['J','0','0','0','0','1','1','1','0','0'],
  ['K','1','0','0','0','0','0','0','1','1'],
  ['L','0','0','1','0','0','0','0','1','1'],
  ['M','1','0','1','0','0','0','0','1','0'],
  ['N','0','0','0','0','1','0','0','1','1'],
  ['O','1','0','0','0','1','0','0','1','0'],
  ['P','0','0','1','0','1','0','0','1','0'],
  ['Q','0','0','0','0','0','0','1','1','1'],
  ['R','1','0','0','0','0','0','1','1','0'],
  ['S','0','0','1','0','0','0','1','1','0'],
  ['T','0','0','0','0','1','0','1','1','0'],
  ['U','1','1','0','0','0','0','0','0','1'],
  ['V','0','1','1','0','0','0','0','0','1'],
  ['W','1','1','1','0','0','0','0','0','0'],
  ['X','0','1','0','0','1','0','0','0','1'],
  ['Y','1','1','0','0','1','0','0','0','0'],
  ['Z','0','1','1','0','1','0','0','0','0'],
  ['-','0','1','0','0','0','0','1','0','1'],
  ['.','1','1','0','0','0','0','1','0','0'],
  [' ','0','1','1','0','0','0','1','0','0'],
  ['*','0','1','0','0','1','0','1','0','0'],
  ['$','0','1','0','1','0','1','0','0','0'],
  ['/','0','1','0','1','0','0','0','1','0'],
  ['+','0','1','0','0','0','1','0','1','0'],
  ['%','0','0','0','1','0','1','0','1','0']
];

Start / Stop Characters for Code 39

Code 39 uses an identical non-encodable symbol for both start and stop characters. Usually, the barcode generator will add those two characters to the symbol automatically. When using a barcode font for Code 39, the start/stop-character is traditionally mapped to the "*" character. Formatting a string like "*12345*" with a Code 39 barcode font will then create a valid barcode (albeit without check digit). To encode a "*" with Code 39, use the combination "/B" (see table below).

Check Digit for Code 39

Code 39 uses a modulo 43 checksum scheme. The characters are summed up, modulo divided by 43, the reminder is the check character. Any character from the code set can be check character, even letters. A Code 39 without check character encoding "12345":

Code 39 without Check Digit

The same data now with check character ("F"):

Code 39 with Check Digit

When creating Code 39 with a check digit, the check character is usually not transmitted with the actual data. In most cases this behaviour must be activated manually in the barcode scanner. Consult your scanner's manual.

Character Table Code 39 Extended

Code 39 Extended code table. ASCII character to the left, the combination to encode to the right. E.g., to encode a lowercase "a" into the code, one would have to actually encode "+A":

NUL %U SUB $Z 4 4 N N h +H
SOH $A ESC %A 5 5 O O i +I
STX $B FS %B 6 6 P P j +J
ETX $C GS %C 7 7 Q Q k +K
EOT $D RS %D 8 8 R R l +L
ENQ $E US %E 9 9 S S m +M
ACK $F SP Space : /Z T T n +N
BEL $G ! /A ; %F U U o +O
BS $H " /B < %G V V p +P
HT $I # /C = %H W W q +Q
LF $J $ /D > %I X X r +R
VT $K % /E ? %J Y Y s +S
FF $L & /F ยง %V Z Z t +T
CR $M ' /G A A [ %K u +U
SO $N ( /H B B \ %L v +V
SI $O ) /I C C ] %M w +W
DLE $P * /J D D ^ %N x +X
DC1 $Q + /K E E _ %O y +Y
DC2 $R , /L F F ' %W z +Z
DC3 $S - - G G a +A { %P
DC4 $T . . H H b +B | %Q
NAK $U / /O I I c +C } %R
SYN $V 0 0 J J d +D ~ %S
ETB $W 1 1 K K e +E DEL %T
CAN $X 2 2 L L f +F DEL %X
EM $Y 3 3 M M g +G DEL %Z

All Softmatic barcode generators will automatically generate the appropriate two symbol codes if the data contains a character from the extended set, e.g. a small cap letter or a control character.

When using Code 39 Extended the barcode scanner has to convert the encoded character pairs to the intended value. For instance, when the code contains the sequence "+A" the scanner must output "a". For most barcode scanners this conversion has to be enabled manually, consult your scanner's manual.

Code 39 vs Code 128

Another popular choice to encode alphanumeric characters is Code 128. The biggest advantage of Code 128 that it is more compact than Code 39 when encoding small cap letters. Code 39 encoding "ABCabc123":

Code 39 Small Cap Letters

The same data as a Code 128 symbol (both codes were created with a module width of 0.5mm):

Code 128 Small Cap Letters

In addition, Code 128 features a very compact purely numeric encoding mode. Code 39 is generally a bad choice for larger amounts of data (the maximum length is around 20 characters). For more info see our comparison Code 128 vs Code 39.

Code 39 in Excel, Word or Google Docs

Code 39 is a good choice for embedding barcodes in your spreadsheet or text document. Applications include catalogs, pricelists, inventories with article numbers or serial numbers. The easiest and most straight forward way of creating Code 39 is with a Code 39 barcode font. As we've seen above, the font can create a valid barcode simply by adding "*" to the data. For creating Code 39 Extended or when a check digit is required, a macro or add-in is needed to do the necessary calculations and data conversion, for example the Softmatic barcode add-in for Excel.

Code 39 Fonts - The Space / Underscore Issue

Special caution is required when encoding data that contains a "space" or "blank", like "CODE 39". In most applications, a blank will be displayed as such, i.e. an empty space, no matter what the font contains at this specific character position. The Softmatic barcode fonts for Code 39 have the bit pattern for the space symbol at the "Underscore" character position (this position was chosen way back in 1991 because the Code 39 character set does not contain the "_"). Hence, to encode "CODE 39" with the font, you'd have to enter "CODE_39". Note that this only applies to font-based barcode creation; the Softmatic barcode extensions and generators do not use barcode fonts and data can be entered as is.

Code 39 Fonts - The Asterisk / Bold Issue

Another delightful pitfall with Code 39 barcode fonts is the auto-formatting that some Microsoft applications perform (namely Word and older versions of Excel): Entering a string like "*12345*" will remove the asterisks and render the text "12345" in bold. Recall that the "*" is the start / stop character of Code 39. Without the asterisk the barcode symbol is not valid and will not scan. Deactivate the respective option in Tools > AutoCorrect > AutoCorrect Options.

Create Code 39 / 39 Extended Barcodes in Illustrator, InDesign

Easy to use barcode plug-ins and extensions for Adobe InDesign, Illustrator und Photoshop. For more videos, see the Softmatic Youtube Channel

The Softmatic barcode plug-ins and extensions for InDesign, Illustrator and Photoshop are available from the Softmatic store.

Stand-alone Barcode Generator for Code 39

Softmatic BarcodePlus V5 creates Code 39 and will export the barcode as PDF / SVG (resolution-independent vector) oder raster image (PNG, TIFF). The app will automatically select Code 39 Extended if the data requires it:

Code 39 Barcode Generator

Bulk Generator for Code 39

For mass creation of Code 39, see BarcodeFactory, Softmatic's bulk barcode generator: