On Wednesday, May 30, 2012 2:27:18 PM UTC-5, Charlie Bursell wrote:
> Has anyone implemented the mod10 check digit algorithm in Tcl? If so would you be kind enough to post a copy
>
> Thks
Thanks for the replies. I finally remember that I wrote one of these back in 1999. Here is what I came up with: (How do I add an attachment?)
###########################################################################
# compute_ mod10.tcl
#
# Calulates the Mod 10 check digit of a number IAW with HL7 standard 2.2
# Page 2-11
#
#
# Algorithm - Assume you have an identifier = 12345. Take the odd digit
# position starting from the right, i.e., 531, multiply this number by 2
# to get 1062. Take the even digit positions, starting from the right
# (i.e., 42), prepend these to the 1062 to get 421062. Add all of these
# six digit together to get 15. Subtract this number from the next higher
# multiple of 10, i.e., 20 - 15 to get 5. The Mod10 check digit is 5.
#
###########################################################################
proc compute_mod10 {num} {
#
# Remove leading zeros. They do not affect calculation and will cut
# down on times through loop. Then make a list of number and reverse
# the order.
#
set num [string trimleft $num 0] ;# Input number w/o leading zeros
set numlist [split $num ""] ;# Numbers in a list
set revnum "" ;# Holds reversed numbers
#
# Reverse the numbers since we must accumulate from right
#
while {$numlist ne ""} {lvarpush revnum [lvarpop numlist]}
#
# Set Odd/even flag. If the length is even, we start with even
# else we start with odd
#
set ODDFLAG 1
set odd "" ;# Stores Odd numbers
set even "" ;# Stores even numbers
#
# Loop through reversed numbers and get odd and even positions
#
foreach digit $revnum {
if {$ODDFLAG} {
append odd $digit
} else {
append even $digit
}
set ODDFLAG [expr $ODDFLAG ^ 1] ;# Flip flag
}
if {$odd eq ""} {set odd 0} ;# Just in case
if {$even eq ""} {set even 0} ;# Just in case
#
# Muliply odd by 2 and prepend to even
#
append even [expr {[string trimleft $odd 0] * 2}]
set newnum [split $even ""] ;# Numbers to list
set total 0 ;# Accumulator
#
# Add all digits together
#
foreach digit $newnum { incr total $digit }
#
# Subtract from next highest multiple of 10
# Return that value
#
set diff [expr {$total % 10}]
if {$diff} {set diff [expr {10 - $diff}]}
set next10 [expr {$total + $diff}]
# Return mod10 value
return [expr {$next10 - $total}]
}