SRIV Sept 19,2010 I had a need to validate IBAN account numbers, so following the example on Wikipedia I wrote a script to do the task. Feel free to test against your bank account numbers and include the country test in the switch with a note saying it works for you.
#!/usr/bin/env tclsh # Steve Redler IV SR Technology Sept 19, 2010 # Validating an International Bank Account Number # as per http://en.wikipedia.org/wiki/International_Bank_Account_Number set iban "GB82 WEST 1234 5698 7654 32" set iban0 [string map {" " ""} [string toupper $iban]] puts "iban0=$iban0" switch -- [string range $iban0 0 1] { HU {if {[string length $iban0] != 28} { puts "IBAN must be 28 characters for Hungary" exit 0} } DE {if {[string length $iban0] != 22} { puts "IBAN must be 22 characters for Germany" exit 0} } IS {if {[string length $iban0] != 26} { puts "IBAN must be 26 characters for Iceland" exit 0} } GB {if {[string length $iban0] != 22} { puts "IBAN must be 22 characters for United Kingdom" exit 0} } PL {if {[string length $iban0] != 28} { puts "IBAN must be 28 characters for POLAND" exit 0} } } set iban1 "[string range $iban0 4 end][string range $iban0 0 3]" puts "iban1=$iban1" set iban2 "" foreach char [split $iban1 ""] { set ascii [scan $char %c] if {$ascii >= 65} { append iban2 [expr $ascii -55] } else { append iban2 $char } puts "ascii $ascii char $char $iban2" } set iban2 [string trimleft $iban2 0] puts "iban2=$iban2" set modulus [expr $iban2 % 97] puts "modulus=$modulus" if {$modulus == 1} { puts "IBAN number is valid" } else { puts "IBAN number is invalid" }
MaxJarek: In tcllib we have valtype::iban for IBAN validation.
package require valtype::iban try { valtype::iban validate GB82WEST12345698765432 } on error {result option} { puts $result }
HolgerJ provides a snit-free proc for validating IBANs. 2023-07-27
#################################################################### ## Validation of IBAN numbers. # # References: # http://en.wikipedia.org/wiki/International_Bank_Account_Number # https://www.iban.com/structure # # # File name: iban-0.1.tm #################################################################### namespace eval ::iban { # Not all countries are already in the SEPA system. Nevertheless, they may use IBANs. array set ibanLengths { AL 28 AD 24 AT 20 AZ 28 BH 22 BY 28 BE 16 BA 20 BR 29 BG 22 BI 27 CR 22 HR 21 CY 28 CZ 24 DK 18 DJ 27 DO 28 EG 29 SV 28 EE 20 FO 18 FI 18 FR 27 GE 22 DE 22 GI 23 GR 27 GL 18 GT 28 VA 22 HU 28 IS 26 IQ 23 IE 22 IL 23 IT 27 JO 30 KZ 20 XK 20 KW 30 LV 21 LB 28 LY 25 LI 21 LT 20 LU 20 MT 31 MR 27 MU 30 MD 24 MC 27 MN 20 ME 22 NL 18 NI 28 MK 19 NO 15 PK 24 PS 29 PL 28 PT 25 QA 29 RO 24 RU 33 LC 32 SM 27 ST 25 SA 24 RS 22 SC 31 SK 24 SI 19 SO 23 ES 24 SD 18 SE 24 CH 21 TL 23 TN 24 TR 26 UA 29 AE 23 GB 22 VG 24 } ;# array set charValues { A 10 B 11 C 12 D 13 E 14 F 15 G 16 H 17 I 18 J 19 K 20 L 21 M 22 N 23 O 24 P 25 Q 26 R 27 S 28 T 29 U 30 V 31 W 32 X 33 Y 34 Z 35 } ;# list proc validate {iban} { # Validate an International Bank Account Number # iban - IBAN to be validated # Returns the IBAN with capitalised characters if the check digits are correct. Throws an error with # an error message if the IBAN's check digits are incorrect, the length of the IBAN is incorrect # or the first two characters don't specify a valid country code. variable ibanLengths variable charValues set iban [string toupper $iban] if {![regexp {^[A-Z]{2}[0-9A-Z]+$} $iban]} { return -code error "IBAN number, expected two-letter country code followed by alphanumerics" } ;# if set country [string range $iban 0 1] if {![info exists ibanLengths($country)]} { return -code error "IBAN number, unknown country code '$country'" } ;# if set expectedLength $ibanLengths($country) set actualLength [string length $iban] if {$actualLength != $expectedLength} { return -code error "IBAN number of country '$country' is expected to be of length $expectedLength, not $actualLength." } ;# if set number [string range $iban 4 end][string range $iban 0 3] set number [string map $charValues $number] set number [string trimleft $number 0] if {($number % 97) != 1} { return -code error "IBAN number '$iban', check digits don't match." } ;# if return $iban } ;# proc validate } ;# namespace package provide ::iban 0.1 proc test {} { # Test proc with an example IBAN of every country where IBANs are defined. set ibans { AL35202111090000000001234567 AD1400080001001234567890 AT483200000012345864 AZ77VTBA00000000001234567890 BH02CITI00001077181611 BY86AKBB10100000002966000000 BE71096123456769 BA393385804800211234 BR1500000000000010932840814P2 BG18RZBB91550123456789 BI1320001100010000123456789 CR23015108410026012345 HR1723600001101234565 CY21002001950000357001234567 CZ5508000000001234567899 DK9520000123456789 DJ2110002010010409943020008 DO22ACAU00000000000123456789 EG800002000156789012345180002 SV43ACAT00000000000000123123 EE471000001020145685 FO9264600123456789 FI1410093000123458 FR7630006000011234567890189 GE60NB0000000123456789 DE75512108001245126199 GI56XAPO000001234567890 GR9608100010000001234567890 GL8964710123456789 GT20AGRO00000000001234567890 VA59001123000012345678 HU93116000060000000012345676 IS750001121234563108962099 IQ20CBIQ861800101010500 IE64IRCE92050112345678 IL170108000000012612345 IT60X0542811101000000123456 JO71CBJO0000000000001234567890 KZ244350000012344567 XK051212012345678906 KW81CBKU0000000000001234560101 LV97HABA0012345678910 LB92000700000000123123456123 LY38021001000000123456789 LI7408806123456789012 LT601010012345678901 LU120010001234567891 MT31MALT01100000000000000000123 MR1300020001010000123456753 MU43BOMM0101123456789101000MUR MD21EX000000000001234567 MC5810096180790123456789085 MN580050099123456789 ME25505000012345678951 NL02ABNA0123456789 NI79BAMC00000000000003123123 MK07200002785123453 NO8330001234567 PK36SCBL0000001123456702 PS92PALS000000000400123456702 PL10105000997603123456789123 PT50002700000001234567833 QA54QNBA000000000000693123456 RO66BACX0000001234567890 RU0204452560040702810412345678901 LC14BOSL123456789012345678901234 SM76P0854009812123456789123 ST23000200000289355710148 SA4420000001234567891234 RS35105008123123123173 SC74MCBL01031234567890123456USD SK8975000000000012345671 SI56192001234567892 SO061000001123123456789 ES7921000813610123456789 SD8811123456789012 SE7280000810340009783242 CH5604835012345678009 TL380010012345678910106 TN5904018104004942712345 TR320010009999901234567890 UA903052992990004149123456789 AE460090000000123456789 GB33BUKB20201555555555 VG07ABVI0000000123456789} foreach iban $ibans { puts [::iban::validate $iban] } ;# foreach } ;# proc test