International Bank Account Number/fr

From Free Pascal wiki
Jump to navigationJump to search

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

Le numéro de compte bancaire international dit IBAN (International Bank Account Number) est une norme internationale pour numéroter les comptes bancaires. C'est la norme ISO 13616. L'IBAN consiste en 34 caractères alphanumériques, comprenant un code pays, deux chiffres de contrôle et un numéro de compte bancaire détaillé.

Le code pays suit la norme ISO 3166-1 alpha-2 Les chiffres de contrôle sont calculés selon la norme ISO 7064 (MOD97-10).

Fonction IsValidIban

Function IsValidIban checks is International Bank Account Number valid. Function StrMOD97 you find here 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.