@ms61:
Hier eine um 15-20 % schnellere Version:
Delphi-Quellcode:
FUNCTION IsIBAN(const s:string):boolean;
var len,cs:integer;
FUNCTION GetCheckSum(first,last:integer):boolean;
var i:integer; c:integer;
begin
for i:=first to last do begin
c:=Ord(s[i])-48;
case c of
0..9 : cs:=(cs*10+c) mod 97;
17..42 : cs:=(((cs*10+(c-7) Div 10) mod 97)*10+(c-7) Mod 10) Mod 97;
else Exit(False);
end;
end;
result:=true;
end;
begin
len:=Length(s);
if (len<5) or (len>34) then Exit(false);
cs:=0;
if not GetCheckSum(5,len) then Exit(false);
if not GetCheckSum(1,4) then Exit(false);
result:=cs=1;
end;
Noch deutlich schneller geht es, wenn man eine Tabelle benutzt um die "teuren" Mod-Operationen zu vermeiden.
Nachteil : Die Tabelle muß entweder als Konstante hinterlegt oder bei Programmstart einmalig gefüllt werden,
was für die Massenverarbeitung aber sicherlich kein Hindernis ist.
Zum Beispiel so :
Delphi-Quellcode:
var
m97tab:array[0..96,0..9] of byte;
PROCEDURE FillM97Tab;
var i,j:Integer;
begin
for i:=0 to 96 do
for j:=0 to 9 do
m97tab[i,j]:=(i*10+j) Mod 97;
end;
FUNCTION IsIBAN2(const s:string):boolean;
var len:integer; cs:byte;
FUNCTION GetCheckSum(first,last:integer):boolean;
var i:integer; c:integer;
begin
for i:=first to last do begin
c:=Ord(s[i])-48;
case c of
0..9 : cs:=m97tab[cs,c];
17..42 : cs:=m97tab[m97tab[cs,(c-7) Div 10],(c-7) Mod 10];
else Exit(False);
end;
end;
result:=true;
end;
begin
len:=Length(s);
if (len<5) or (len>34) then Exit(false);
cs:=0;
if not GetCheckSum(5,len) then Exit(false);
if not GetCheckSum(1,4) then Exit(false);
result:=cs=1;
end;
Gemessene Zeiten für 1 Mio Durchläufe:
CheckIban : 249 ms
IsIBAN : 203 ms
IsIBAN2 : 94 ms