Алгоритм проверки ISBN
[ Вадим Беркович ]
Исходный код класса приведен ниже.
Untitled
unit gcISBNSpeller;
{
--- Описание
Класс проверки ISBN
--- Имя и параметры
TISBNSpeller
--- Обязанности
Проверяет корректность ISBN
- корректность знаков
- код страны
- число цифр
- контрольную сумму
При нахождении ошибки возбуждает исключение EISBNSpellerException
с указанием типа ошибки
coded by
vadim berckovich
last changes
xelby 11.09.02
}
interface
uses SysUtils;
type
{ типы ошибок в ISBN }
TISBNErrorType = (isbnEmptyISBN, isbnInvalidLength, isbnDigitCount,
isbnUncknownChar, isbnUncknownCountryCode, isbnInvalidChecksum);
{ класс исключения, вызываемого при нахождении ошибки в ISBN }
EISBNSpellerException = class(Exception)
private
FErrorType: TISBNErrorType;
public
constructor CreateRes(ErrorType: TISBNErrorType; ResStringRec: PResStringRec); overload;
constructor CreateResFmt(ErrorType: TISBNErrorType; ResStringRec: PResStringRec;
const Args: array of const); overload;
property ErrorType: TISBNErrorType read FErrorType write FErrorType;
end;
{ класс проверки ISBN }
TgcISBNSpeller = class
private
FAllowableCountryCodes: string;
public
constructor Create;
{ Вызов проверки. При нахождении ошибки вызывает исключения класса EISBNSpellerException }
procedure Execute(const ISBNValue: string);
{ строка с цифрами приемлемых кодов стран. Пр пустом поле проверка не производится }
property AllowableCountryCodes: string
read FAllowableCountryCodes write FAllowableCountryCodes;
end;
resourcestring
{ error strings }
isbn_EmptyISBN = 'ISBN пуст';
isbn_InvalidLength = 'Неверная длинна ISBN';
isbn_DigitCount = 'Неверное число цифр в ISBN - должно быть 10';
isbn_UncknownChar = 'В ISBN недопустимый знак: %s';
isbn_UncknownCountryCode = 'Внимание: недопустимый код страны: %s';
isbn_InvalidChecksum = 'Неверная контрольная сумма ISBN. '
+ 'Контрольная сумма ISBN может быть цифрой от 0 до 9 или латинской X. Должно быть: %s';
const
cyrillicX = 'Х';
latinX = 'X';
implementation
{ TISBNSpeller }
constructor TgcISBNSpeller.Create;
begin
{ по умолчанию принимать только код России }
AllowableCountryCodes := '5';
end;
procedure TgcISBNSpeller.Execute(const ISBNValue: string);
var
check_sum : Integer;
i,j,a : Integer;
str,str_sum, strISBN : String;
begin
check_sum:= 0;
strISBN := ISBNValue;
{ проверить на цифры или X }
if strISBN = EmptyStr then
raise EISBNSpellerException.CreateRes(isbnEmptyISBN, @isbn_EmptyISBN);
{ проверить длину }
if Length(strISBN) <> 13 then
raise EISBNSpellerException.CreateRes(isbnInvalidLength, @isbn_InvalidLength);
{ смерть дефисам }
strISBN := StringReplace(strISBN,'-','',[rfReplaceAll, rfIgnoreCase]);
{ проверить число цифр }
if Length(strISBN) <> 10 then
raise EISBNSpellerException.CreateRes(isbnDigitCount, @isbn_DigitCount);
{ расчет котрольной суммы }
j:=1;
for i := Length(strISBN) downto 2 do
begin
try
check_sum := check_sum + i * StrToInt(Copy(strISBN, j, 1));
inc(j);
except
raise EISBNSpellerException.CreateResFmt(isbnUncknownChar,
@isbn_UncknownChar, [Copy(strISBN, j, 1)]);
end;
end;
{ проверить код страны }
if (length(AllowableCountryCodes) > 0) and (pos(strISBN[1], AllowableCountryCodes) = -1) then
raise EISBNSpellerException.CreateResFmt(isbnUncknownCountryCode,
@isbn_UncknownCountryCode, [strISBN[1]]);
a := check_sum mod 11;
if a = 0 then check_sum := 0
else check_sum := 11 - a;
str := Copy(strISBN, Length(strISBN), 1);
if (check_sum = 10) then
begin { должна быть латинская X }
if (UpperCase(str) <> latinX) and (UpperCase(str) <> cyrillicX) then
raise EISBNSpellerException.CreateResFmt(isbnInvalidChecksum,
@isbn_InvalidChecksum, [latinX]);
end
else
if (check_sum <> StrToInt(str)) then
raise EISBNSpellerException.CreateResFmt(isbnInvalidChecksum,
@isbn_InvalidChecksum, [IntToStr(check_sum)]);
end;
{ EISBNSpellerException }
constructor EISBNSpellerException.CreateRes(ErrorType: TISBNErrorType;
ResStringRec: PResStringRec);
begin
self.ErrorType := ErrorType;
inherited CreateRes(ResStringRec);
end;
constructor EISBNSpellerException.CreateResFmt(ErrorType: TISBNErrorType;
ResStringRec: PResStringRec; const Args: array of const);
begin
self.ErrorType := ErrorType;
inherited CreateResFmt(ResStringRec, Args);
end;
end.
Приведенный компонент может быть по Вашему запросу преобразован в компонент ActiveX для использования в любых
средах разработки под MS Windows, в.т.ч. VisualBasic, PowerBuilder, 1C etc.
Весь материал, размещенный на сайте www.bookresearch.ru, является собственностью авторов соответствующих материалов.
Любая перепечатка и перенос материалов на другие сайты возможны только с разрешения авторов и администратора сайта.
Любой может предложить свой материал для публикации у нас. Пишите администратору сайта.
|