program Project1;
{$mode objfpc}{$H+}
Uses Classes, Sysutils, regexpr;
Const
S10:String='RC473124829DE';
Pattern:String='(\w{2})(\d{9})(\w{2})';
Weights:array[0..7] of Integer=(8,6,4,2,3,5,9,7);
CheckDigits:Array[0..11] Of Integer=(0,1,2,3,4,5,6,7,8,9,0,5);
Var
SV,SN,CO:String;
CD:Integer;
IsValid:Boolean;
Function CheckS10(Const AS10:String;var AService:String;var ASerialNo:String;Var ACheckDigit:Integer;var ACountry:String):Boolean;
Var
regex:TRegExpr;
b:Boolean;
i:Integer;
s:Integer;
sn:Integer;
cd:Integer;
Begin
Result:=False;
s:=0;
If Length(AS10)<>13 Then Exit;
regex:=TRegexpr.Create;
regex.ModifierI:=True;
regex.ModifierG:=True;
regex.Expression:=Pattern;
regex.InputString:=AS10;
b:=regex.Exec;
If Not b Then Exit; //Regex failed
If regex.SubExprMatchCount<>3 Then Exit; //Must be 3 SubMatches, else not valid S10-Format
AService:=Regex.Match[1]; //Service
ASerialNo:=LeftStr(regex.Match[2],8); //Left 8 characters are the SerialNumber
sn:=ASerialNo.ToInteger; //SerialNumber as Integer
ACheckDigit:=regex.Match[2].ToInteger Mod 10; //CheckDigit As Integer
ACountry:=regex.Match[3]; //Country Of Origin
For i:=7 DownTo 0 Do //Iterating backwards, since parsing the Serialnumber from right to left
Begin
cd:=sn mod 10; //Get the right most Digit
s:=s+cd*Weights[i]; //Build Sum
sn:=sn Div 10; //Cut off right most Digit
end;
cd:=CheckDigits[11-(s mod 11)]; //Get the CheckDigit from Lookup-Array
Result:=(ACheckDigit=cd);
regex.Free;
End;
begin
IsValid:=CheckS10(S10,SV,SN,CD,CO);
Writeln(S10);
Writeln(SV);
Writeln(SN);
Writeln(CD);
Writeln(CO);
Writeln(IsValid);
Readln;
end.