International Bank Account Number: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: International Bank Account Number
| Old | New | Line | |
|---|---|---|---|
| 1 | + | The International Bank Account Number (IBAN) is an international standard for numbering bank accounts. It is an ISO 13616 standard. The IBAN consists of up to 34 alphanumeric characters, comprising a country code, two check digits and a bank account number. | |
| 2 | + | ||
| 3 | + | | Country | IBAN formatting example | | |
| 4 | + | |----------------|-------------------------------------------| | |
| 5 | + | | Belgium | `BE71 0961 2345 6769` | | |
| 6 | + | | Brazil | `BR15 0000 0000 0000 1093 2840 814 P2` | | |
| 7 | + | | Costa Rica | `CR99 0000 0000 0000 8888 88` | | |
| 8 | + | | France | `FR76 3000 6000 0112 3456 7890 189` | | |
| 9 | + | | Ireland | `IE12 BOFI 9000 0112 3456 78` | | |
| 10 | + | | Germany | `DE91 1000 0000 0123 4567 89` | | |
| 11 | + | | Greece | `GR96 0810 0010 0000 0123 4567 890` | | |
| 12 | + | | Mauritius | `MU43 BOMM 0101 1234 5678 9101 000 MUR` | | |
| 13 | + | | Pakistan | `PK70 BANK 0000 1234 5678 9000` | | |
| 14 | + | | Poland | `PL10 1050 0099 7603 1234 5678 9123` | | |
| 15 | + | | Romania | `RO09 BCYP 0000 0012 3456 7890` | | |
| 16 | + | | Saint Lucia | `LC14 BOSL 1234 5678 9012 3456 7890 1234` | | |
| 17 | + | | Saudi Arabia | `SA44 2000 0001 2345 6789 1234` | | |
| 18 | + | | Spain | `ES79 2100 0813 6101 2345 6789` | | |
| 19 | + | | Sweden | `SE87 3000 0000 0101 2345 6789` | | |
| 20 | + | | Switzerland | `CH56 0483 5012 3456 7800 9` | | |
| 21 | + | | United Kingdom | `GB98 MIDL 0700 9312 3456 78` | | |
| 22 | + | ||
| 23 | + | Permitted IBAN characters are the digits *0* to *9* and the 26 Latin alphabetic characters *A* to *Z*. This applies even in countries where these characters are not used in the national language (e.g., Thailand). | |
| 24 | + | ||
| 25 | + | The country code uses ISO 3166-1 alpha-2. The check digits are calculated according to [[ISO 7064]] (MOD97-10) using [[ISO 7064|StrMOD97]]. | |
| 26 | + | ||
| 27 | + | ## Function IsValidIBAN | |
| 28 | + | ||
| 29 | + | Function IsValidIBAN() checks if an IBAN is valid. Code from forum member **wp**. | |
| 30 | + | ||
| 31 | + | ``` pascal | |
| 32 | + | Program iban; | |
| 33 | + | ||
| 34 | + | {$mode objFPC} {$H+} | |
| 35 | + | ||
| 36 | + | Uses | |
| 37 | + | StrUtils, SysUtils; | |
| 38 | + | ||
| 39 | + | // Calculate Modulo 97-10 | |
| 40 | + | function StrMOD97(s: String): integer; | |
| 41 | + | const | |
| 42 | + | modu = 97; | |
| 43 | + | var | |
| 44 | + | sx: String; | |
| 45 | + | isx, ic, p: Integer; | |
| 46 | + | begin | |
| 47 | + | p := Length(s); | |
| 48 | + | while (p > 9) do | |
| 49 | + | begin | |
| 50 | + | sx := Copy(s, 1, 9); | |
| 51 | + | Delete(s, 1, 9); | |
| 52 | + | isx := StrToInt(sx); | |
| 53 | + | ic := isx mod modu; | |
| 54 | + | s := IntToStr(ic) + s; | |
| 55 | + | p := Length(s); | |
| 56 | + | end; | |
| 57 | + | isx := StrToInt(s); | |
| 58 | + | if isx >= modu | |
| 59 | + | then ic := isx mod modu | |
| 60 | + | else ic := isx; | |
| 61 | + | result := ic; | |
| 62 | + | end; | |
| 63 | + | ||
| 64 | + | function ProcessChar(ch: char):string; | |
| 65 | + | begin | |
| 66 | + | if (ch in ['0'..'9']) then | |
| 67 | + | Result := ch | |
| 68 | + | else | |
| 69 | + | // IBAN letter to number algorithm | |
| 70 | + | if (ch in ['A'..'Z', 'a'..'z']) then | |
| 71 | + | result := IntToStr(ord(upCase(ch)) - ord('A') + 10) | |
| 72 | + | else | |
| 73 | + | result := ''; | |
| 74 | + | end; | |
| 75 | + | ||
| 76 | + | // Check IBAN validity | |
| 77 | + | function IsValidIBAN(s: string): boolean; | |
| 78 | + | var | |
| 79 | + | s1: string = ''; | |
| 80 | + | ch: String; | |
| 81 | + | i: Integer; | |
| 82 | + | begin | |
| 83 | + | Result := false; | |
| 84 | + | ||
| 85 | + | // Delete any spaces | |
| 86 | + | s := DelSpace(s); | |
| 87 | + | ||
| 88 | + | // Obvious tests | |
| 89 | + | if Length(s) < 4 then | |
| 90 | + | exit; | |
| 91 | + | if not ((s[1] in ['A'..'Z']) and (s[2] in ['A'..'Z'])) then | |
| 92 | + | exit; | |
| 93 | + | if not ((s[3] in ['0'..'9']) and (s[4] in ['0'..'9'])) then | |
| 94 | + | exit; | |
| 95 | + | ||
| 96 | + | // Process number block first | |
| 97 | + | for i := 5 to Length(s) do | |
| 98 | + | begin | |
| 99 | + | ch := ProcessChar(s[i]); // Convert letters to numbers, keep numbers | |
| 100 | + | if ch = '' then | |
| 101 | + | exit; | |
| 102 | + | s1 := s1 + ch; | |
| 103 | + | end; | |
| 104 | + | // Move country code and check sum to the end of the test string | |
| 105 | + | for i := 1 to 4 do | |
| 106 | + | s1 := s1 + ProcessChar(s[i]); | |
| 107 | + | ||
| 108 | + | result := (StrMOD97(s1) = 1); | |
| 109 | + | end; | |
| 110 | + | ||
| 111 | + | type | |
| 112 | + | TTestRec = record | |
| 113 | + | TestIBAN: String; | |
| 114 | + | Expected: Boolean; | |
| 115 | + | end; | |
| 116 | + | ||
| 117 | + | const | |
| 118 | + | // Expected results validated by https://www.ibancalculator.com/iban_validieren.html | |
| 119 | + | Tests: array[0..10] of TTestRec = ( | |
| 120 | + | (TestIBAN:'GB82 WEST 1234 5698 7654 32'; Expected: true), | |
| 121 | + | (TestIBAN:'GB82 TEST 1234 5698 7654 32'; Expected: false), | |
| 122 | + | (TestIBAN:'GB82 WEST12345698765432'; Expected: true), | |
| 123 | + | (TestIBAN:'GB 82WEST12345698765432'; Expected: true), | |
| 124 | + | (TestIBAN:'GB82 WEST123 456 987 654 32'; Expected: true), | |
| 125 | + | (TestIBAN:'CH93 0076 2011 6238 5295 7'; Expected: true), | |
| 126 | + | (TestIBAN:'IL62 0108 0000 0009 9999 999'; Expected: true), | |
| 127 | + | (TestIBAN:'GR16 0110 1250 0000 0001 2300 695'; Expected: true), | |
| 128 | + | (TestIBAN:'US12 3456 7890 0987 6543 210'; Expected: false), | |
| 129 | + | (TestIBAN:'LC14 BOSL 1234 5678 9012 3456 7890 1234'; Expected: true), | |
| 130 | + | (TestIBAN:'BR15 0000 0000 0000 1093 2840 814 P2'; Expected: true ) | |
| 131 | + | ); | |
| 132 | + | W = 40; | |
| 133 | + | var | |
| 134 | + | i: Integer; | |
| 135 | + | s: String; | |
| 136 | + | ok: Boolean; | |
| 137 | + | begin | |
| 138 | + | for i := 0 to High(Tests) do | |
| 139 | + | begin | |
| 140 | + | s := Tests[i].TestIBAN; | |
| 141 | + | ok := IsValidIBAN(s); | |
| 142 | + | if ok = Tests[i].Expected then | |
| 143 | + | begin | |
| 144 | + | if ok then | |
| 145 | + | WriteLn(s:W, ': Correct IBAN correctly detected') | |
| 146 | + | else | |
| 147 | + | WriteLn(s:W, ': Incorrect IBAN correctly detected.'); | |
| 148 | + | end else | |
| 149 | + | if Tests[i].Expected then | |
| 150 | + | WriteLn(s:W, ': ERROR (Correct IBAN not detected)') | |
| 151 | + | else | |
| 152 | + | WriteLn(s:W, ': ERROR (Incorrect IBAN not detected)'); | |
| 153 | + | end; | |
| 154 | + | ||
| 155 | + | ReadLn; | |
| 156 | + | end. | |
| 157 | + | ``` | |
| 158 | + | ||
| 159 | + | ## See Also | |
| 160 | + | ||
| 161 | + | - [IBAN](https://www.rosettacode.org/wiki/IBAN#Free_Pascal) on RosettaCode.org | |
| 162 | + | ||
| 163 | + | --- | |
| 164 | + | *From the Free Pascal wiki, page "International Bank Account Number", as it stood on 2021-12-02 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
