International Bank Account Number/fi

From Free Pascal wiki
Jump to navigationJump to search

English (en) suomi (fi) français (fr)

Kansainvälinen pankkitilinumero ( IBAN = International Bank Account Number ) on kansainvälinen standardi pankkien tilinumeroista. Se on määritelty ISO 13616 standardissa. IBAN sisältää maksimissaan 34 merkkiä, joka sisältää maa koodin, kaksi tarkistusnumeroa ja yksilöivän pankin tilinumeron.


Maakoodissa ilmoitetaan ISO 3166-1 alpha-2 standardin mukaisesti. Tarkistusnumero lasketaan ISO 7064 (MOD97-10) standardin mukaisesti.

Funktio IsValidIban

Funktio IsValidIban tarkistaa onko kansainvälinen pankkitilinumero sääntöjen mukainen. Funktio StrMOD97 löytyy täältä ISO_7064#Function StrMOD97

Program iban;
 
{$mode objFPC} {$H+}
 
Uses
 StrUtils, SysUtils;
 
// Calculate Modulo 97-10
function StrMOD97(s: String): integer;
const
  modu = 97;
var
  sx: String;
  isx, ic, p: Integer;
begin
   p := Length(s);
   while (p > 9) do
     begin
       sx := Copy(s, 1, 9);
       Delete(s, 1, 9);
       isx := StrToInt(sx);
       ic := isx mod modu;
       s := IntToStr(ic) + s;
       p := Length(s);
     end;
   isx := StrToInt(s);
   if isx >= modu
     then ic := isx mod modu
   else ic := isx;
  result := ic;
end;
 
function ProcessChar(ch: char):string;
begin
  if (ch in ['0'..'9']) then
    Result := ch
  else
  // IBAN letter to number algorithm
  if (ch in ['A'..'Z', 'a'..'z']) then
    result := IntToStr(ord(upCase(ch)) - ord('A') + 10)
  else
    result := '';
end;  
 
// Check IBAN validity
function IsValidIBAN(s: string): boolean;
var
  s1: string = '';
  ch: String;
  i: Integer;
begin
  Result := false;
 
  // Delete any spaces
  s := DelSpace(s);
 
  // Obvious tests
  if Length(s) < 4 then
    exit;
  if not ((s[1] in ['A'..'Z']) and (s[2] in ['A'..'Z'])) then
    exit;
  if not ((s[3] in ['0'..'9']) and (s[4] in ['0'..'9'])) then
    exit;
 
  // Process number block first
  for i := 5 to Length(s) do
  begin
    ch := ProcessChar(s[i]);    // Convert letters to numbers, keep numbers
    if ch = '' then
      exit;
    s1 := s1 + ch;
  end;
  // Move country code and check sum to the end of the test string
  for i := 1 to 4 do
    s1 := s1 + ProcessChar(s[i]);
 
  result := (StrMOD97(s1) = 1);
end;
 
type
  TTestRec = record
    TestIBAN: String;
    Expected: Boolean;
  end;
 
const
  // Expected results validated by https://www.ibancalculator.com/iban_validieren.html
  Tests: array[0..10] of TTestRec = (
    (TestIBAN:'GB82 WEST 1234 5698 7654 32';             Expected: true),
    (TestIBAN:'GB82 TEST 1234 5698 7654 32';             Expected: false),
    (TestIBAN:'GB82 WEST12345698765432';                 Expected: true),
    (TestIBAN:'GB 82WEST12345698765432';                 Expected: true),
    (TestIBAN:'GB82 WEST123 456 987 654 32';             Expected: true),
    (TestIBAN:'CH93 0076 2011 6238 5295 7';              Expected: true),
    (TestIBAN:'IL62 0108 0000 0009 9999 999';            Expected: true),
    (TestIBAN:'GR16 0110 1250 0000 0001 2300 695';       Expected: true),
    (TestIBAN:'US12 3456 7890 0987 6543 210';            Expected: false),
    (TestIBAN:'LC14 BOSL 1234 5678 9012 3456 7890 1234'; Expected: true),
    (TestIBAN:'BR15 0000 0000 0000 1093 2840 814 P2';    Expected: true )
  );
  W = 40;
var
  i: Integer;
  s: String;
  ok: Boolean;
begin
  for i := 0 to High(Tests) do
  begin
    s := Tests[i].TestIBAN;
    ok := IsValidIBAN(s);
    if ok = Tests[i].Expected then
    begin
      if ok then
        WriteLn(s:W, ': Correct IBAN correctly detected')
      else
        WriteLn(s:W, ': Incorrect IBAN correctly detected.');
    end else
    if Tests[i].Expected then
      WriteLn(s:W, ': ERROR (Correct IBAN not detected)')
    else
      WriteLn(s:W, ': ERROR (Incorrect IBAN not detected)');
  end;
 
  ReadLn;
end.