[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 [http://www.barcodeisland.com/ean8.phtml]. ====== # EAN 8 barcode generation # Specification described at http://www.barcodeisland.com/ean8.phtml # Based heavily on code by Pascal Scheffers from http://wiki.tcl.tk/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; } # All EAN8 codes start with 'left guard bars': 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 . [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} ====== <> Barcode