## EAN-8 Barcode Generator

MG Oct 5th 2008 - I recently bought a cheap barcode scanner to play with, and am trying to reproduce the barcodes it scans on-screen. Based very, very heavily on PS's code for EAN-13 generation, here's similar code which produces EAN-8 barcodes. You can find the spec for EAN-8 that I used here [1 ].

```# EAN 8 barcode generation
# Specification described at http://www.barcodeisland.com/ean8.phtml
# Based heavily on code by Pascal Scheffers from https://wiki.tcl-lang.org/10538

proc ean8_csum {number} {

set sum 0

foreach {odd even} [split "[string range \${number} 0 6]0" ""] {
incr sum [expr {\$odd*3}]
incr sum [expr {\$even*1}]
}

set check [expr {\$sum % 10}]
if { \$check > 0 } {
return [expr {10 - \$check}]
}

return \$check;

};# ean8_csum

proc ean8 {number} {

if { [string length \$number] != 7 && [string length \$number] != 8 } {
puts "Must be 7 or 8 digits long"
return;
}

# EAN8 digits, the ones represent black bars, the zeroes white space.
# Two pairs of digits: lefthand-odd(A) and righthand

set digits {
{0 0001101 1110010}
{1 0011001 1100110}
{2 0010011 1101100}
{3 0111101 1000010}
{4 0100011 1011100}
{5 0110001 1001110}
{6 0101111 1010000}
{7 0111011 1000100}
{8 0110111 1001000}
{9 0001011 1110100}
}

# If we get a 7 digit number, append the checkdigit to that. Otherwise, verify checkdigit.
set csum [ean8_csum [string range \$number 0 6]]
if { [string length \$number] == 7 } {
set number \$number[ean8_csum \$number]
} elseif { [string index \$number 7] != \$csum } {
puts "Invalid code"
return;
}

lappend bars 101

# First four digits:
foreach digit [split [string range \$number 0 3] ""] {
lappend bars [lindex [lindex \$digits \$digit] 1]
}

# center guard bars:
lappend bars 01010

# the right hand chars, all encoded the same:
foreach digit [split [string range \$number 4 8] ""] {
lappend bars [lindex [lindex \$digits \$digit] 2]
}

# and the final guards:
lappend bars 101

return [list \$bars \$number];
};# ean8

# Tk demo code:

package require Tk

wm title . "EAN-8 Barcode"

label .lbar -text "Barcode"
entry .barcode -textvariable barcode -width 15
button .show -text show -command do_display
bind . <Return> [list .show invoke]
grid .lbar .barcode .show -sticky nw

canvas .c -width 200 -height 100

grid x .c - -sticky nw

proc do_display { } {
global barcode
if { [string length \$barcode] < 7 } {
bell -displayof .
return;
}

.c delete all
set b [ean8 \$barcode]

set x 25
foreach barset [lindex \$b 0] {
set bars [split \$barset ""]
if { [llength \$bars] == 7 } {
set len 40
} else {
set len 46
}
foreach bar \$bars {
incr x 1
if { \$bar } {
.c create line \$x 15 \$x [expr \$len+15]
}
}
}

# And create the human readable text below it:
.c create text 43 60 -text [string range [lindex \$b 1] 0 3]
.c create text 75 60 -text [string range [lindex \$b 1] 4 8]
};# do_display

set barcode {55123457}

do_display

catch {console show}
```

 Category Barcode