# This is a demo NeoWebScript by Horace Vallas - 3-7-97 according to some info # I found on the web that was attibuted to ICVERIFY by Hal Stiles hstiles@beachnet.com # http://www.beachnet.com/~hstiles/cardtype.html # # You are welcome to use it; however, I make no warranty whatsoever about the # accuracy or usefullness of this script. By using this script, you are agreeing that # I am not responsible for any damage, of any kind whatsoever, to you or to any of # your customers, clients, partners, friends, relatives, children born or unborne, # pets, invisible friends, etc. etc. etc. #=============================================================== # The valCC proc can be used to validate a credit card number as # being legally formed. # # input is the entered card number # return is the type of card (if validated) # or "- unknown-" if it is an unknown or invalid number # # The validation applied (last known date 3/96) is the so called # LUHN Formula (Mod 10) for Validation of Primary Account Number # Validation criteria are: # # 1. number prefix # 2. number of digits # 3. mod10 (for all but enRoute which uses only 1 & 2) # # ... according to the following list of criteria requirements: # # Card Type Prefix Length Check-Digit Algoritm # # MC 51 - 55 16 mod 10 # # VISA 4 13, 16 mod 10 # # AMX 34, 37 15 mod 10 # # Diners Club / 300 - 305, 36, 38 14 mod 10 # Carte Blanche # # Discover 6011 16 mod 10 # # enRoute 2014, 2149 16 - any - # # JCB 3 16 mod 10 # JCB 2131, 1800 15 mod 10 # proc valCC {numIn} { regsub -all { } $numIn {} entered_number set num [split $entered_number {}] ; # a list form of the number set numLen [llength $num] ; # the number of digits in the entered number set type "-unknown-" # first determine the type of card: MC, VISA, AMX, etc. # i.e. test prefix and then number of digits switch -glob [string range $entered_number 0 3] { "51??" - "52??" - "53??" - "54??" - "55??" {if {$numLen == 16} {set type "MasterCard"}} "4???" {if {$numLen == 13 || $numLen == 16} {set type "VISA"}} "34??" - "37??" {if {$numLen == 15} {set type "American Express"}} "300?" - "301?" - "302?" - "303?" - "304?" - "305?" - "36??" - "38??" {if {$numLen == 14} {set type "Diner's Club / Carte Blanche"}} "6011" {if {$numLen == 16} {set type "Discover"}} "2014" - "2149" {if {$numLen == 15} {set type "enRoute"}; return $type ; # early exit for enRoute} "3???" {if {$numLen == 16} {set type "JCB"}} "2131" - "1800" {if {$numLen == 15} {set type "JCB"}} default {set type "-unknown-"} } if {$type == "-unknown-"} { return $type} ; #early exit if we already know it is bad # if prefix and number of digits are ok, # then apply the mod10 check set sum 0 ; # initialize the running sum # sum every digit starting with the RIGHT-MOST digit # on alternate digits (starting with the NEXT-TO-THE-RIGHT-MOST digit) # sum all digits in the result of TWO TIMES the alternate digit # RATHER than the original digit itself # CATCH this summing loop in case there are non-digit values in the # user supplied string if {[catch { ; for {set i [expr $numLen - 1]} {$i >= 0} {} { incr sum [lindex $num $i] if {[incr i -1] >= 0} { foreach adigit [split [expr 2 * [lindex $num $i]] {}] {incr sum $adigit} incr i -1 } } }] != 0} { return "-unknown-" } # emulate a mod 10 (base 10) on the calculated number. # if there is any remainder, then the number IS NOT VALID # so reset type to -unknown- set lsum [split $sum {}] if {[lindex $lsum [expr [llength $lsum] - 1]]} {set type "-unknown-"} return $type }