program Project1;
{$mode objfpc}
{$H+}
type
TS10Info = packed record
ServiceIndicator: array[0..1] of char; // Country of origin ?
SerialNumber: array[0..7] of char;
CheckDigit: char;
Destination: array[0..1] of char; // Country of destination
IsValid: boolean;
end;
function ParseAndValidateAS10(aTracking: string; out aoInfo: TS10Info): boolean;
const
Weights: array[0..7] of byte = (8, 6, 4, 2, 3, 5, 9, 7);
var
i, RunSum: integer;
begin
Result := False;
aoInfo := Default(TS10Info);
// quick exit length has to be 13
if Length(ATracking) <> 13 then
Exit;
system.move(aTracking[1], aoInfo, 13);
with aoInfo do begin
RunSum := 0;
for i := 0 to Length(SerialNumber) - 1 do begin
// check letter pattern
if not (SerialNumber[i] in ['0'..'9']) then
exit;
Inc(RunSum, Weights[i] * (byte(SerialNumber[i]) - Ord('0')));
end;
if 11 - RunSum mod 11 <> byte(CheckDigit) - Ord('0') then
exit;
Result := True;
IsValid := Result;
end;
end;
var
vS10Str: string;
voS10: TS10Info;
begin
vS10Str := 'RC473124829DE';
ParseAndValidateAS10(vS10Str, voS10);
with voS10 do
WriteLn(vS10Str, #9, ServiceIndicator, #9, SerialNumber, #9, CheckDigit,
#9, Destination, #9, IsValid);
vS10Str := 'LW293266916CH';
ParseAndValidateAS10(vS10Str, voS10);
with voS10 do
WriteLn(vS10Str, #9, ServiceIndicator, #9, SerialNumber, #9, CheckDigit,
#9, Destination, #9, IsValid);
vS10Str := 'LW193266916CH';
ParseAndValidateAS10(vS10Str, voS10);
with voS10 do
WriteLn(vS10Str, #9, ServiceIndicator, #9, SerialNumber, #9, CheckDigit,
#9, Destination, #9, IsValid);
Readln;
end.