

 This page uses content from Wikipedia. The original article was at IBAN. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)



The   International Bank Account Number (IBAN)   is an internationally agreed means of identifying bank accounts across national borders with a reduced risk of propagating transcription errors.

The IBAN consists of up to 34 alphanumeric characters:

   first the two-letter ISO 3166-1 alpha-2 country code, 
   then two check digits, and 
   finally a country-specific Basic Bank Account Number (BBAN). 


The check digits enable a sanity check of the bank account number to confirm its integrity even before submitting a transaction.



Task

Validate the following fictitious IBAN:    GB82 WEST 1234 5698 7654 32 



Details of the algorithm can be found on the Wikipedia page.




// List updated to release 72, 25 November 2016, of IBAN Registry (75 countries)
countryCodes$ = "AD24 AE23 AL28 AT20 AZ28 BA20 BE16 BG22 BH22 BR29 BY28 CH21 CR22 CY28 CZ24 DE22 "
countryCodes$ = countryCodes$ + "DK18 DO28 EE20 ES24 FI18 FO18 FR27 GB22 GE22 GI23 GL18 GR27 GT28 HR21 HU28 IE22 "
countryCodes$ = countryCodes$ + "IL23 IQ23 IS26 IT27 JO30 KW30 KZ20 LB28 LC32 LI21 LT20 LU20 LV21 MC27 MD24 ME22 "
countryCodes$ = countryCodes$ + "MK19 MR27 MT31 MU30 NL18 NO15 PK24 PL28 PS29 PT25 QA29 RO24 RS22 SA24 SC31 SE24 "
countryCodes$ = countryCodes$ + "SI19 SK24 SM27 ST25 SV28 TL23 TN24 TR26 UA29 VG24 XK20"
 
sub iban(code$)
// This routine does and should reject codes containing spaces etc.
// Use iban_s() below for otherwise.
    local country, lcode, c, i, ch$
 
    lcode = len(code$)
    country = instr(countryCodes$, upper$(left$(code$, 2)))
 
    if country and lcode = val(mid$(countryCodes$, country + 2, 2)) then
        code$ = right$(code$, lcode - 4) + left$(code$, 4)
        for i = 1 to lcode
            ch$ = mid$(code$, i, 1)
            if ch$ >= "0" and ch$ <= "9" then
                c = c * 10 + asc(ch$) - asc("0")
            elsif ch$ >= "A" and ch$ <= "Z" then
                c = c * 100 + asc(ch$) - 55
            else
                return false
            end if
            c = mod(c, 97)
        next i
        return c = 1
    end if
    return false
end sub
 
sub iban_s(code$)
// strips any embedded spaces and hyphens before validating.
	local i, t$(1), n
 
	i = token(code$, t$(), " -")
	code$ = ""
	for n = 1 to i
		code$ = code$ + t$(n)
	next n
 
    return iban(code$)
end sub
 
sub test(code$, expected)
    local valid, state$
 
    valid = iban_s(code$)
 
    if valid = expected then
    	if valid then
    		state$ = "ok"
    	else
    		state$ = "invalid (as expected)"
    	end if
    else
    	if valid then
    		state$ = "OK!!"
    	else
    		state$ = "INVALID!!"
    	end if
    	state$ = state$ + " (NOT AS EXPECTED)"
    end if
    print code$, "\t ", state$
end sub
 
test("GB82 WEST 1234 5698 7654 32", true)
test("GB82 TEST 1234 5698 7654 32", false)
test("GB81 WEST 1234 5698 7654 32", false)
test("SA03 8000 0000 6080 1016 7519", true)
test("CH93 0076 2011 6238 5295 7", true)