{ Чтение ключевой информации из файлов } unit ReadKey; interface USES GostBase; const cSubstTableNumDelimiter=';'; type tReadKeyResult=( rkrOK , rkrUnknownError , rkrCantOpenFile , rkrCantReadFile , rkrInvalidNumber , rkrNotEnoughNumbers ); tReadKeyErrors=array[tReadKeyResult] of string; const cReadKeyErrors:tReadKeyErrors=( 'Нет ошибок.' , 'Неизвестная ошибка.' , 'Не могу открыть файл.' , 'Нет данных или недостаточно данных в файле.' , 'Неверное число или отсутствие числа в файле.' , 'Недостаточно чисел в файле.' ); type tReadSubstTablResult=( rstrOK , rstrUnknownError , rstrCantOpenFile , rstrCantReadFile , rstrInvalidNumber , rstrNotEnoughNumbers , rstrNotEnoughStrings , rstrInvalidValue ); tReadSubstTablErrors=array[tReadSubstTablResult] of string; const cReadSubstTablErrors:tReadSubstTablErrors=( 'Нет ошибок.' , 'Неизвестная ошибка.' , 'Не могу открыть файл.' , 'Нет данных или недостаточно данных в файле.' , 'Неверное число или отсутствие числа в файле.' , 'Недостаточно чисел в строке.' , 'Недостаточно строк в файле.' , 'Число вне допустимого диапазона.' ); type tReadSyncResult=( rsrOK , rsrUnknownError , rsrCantOpenFile , rsrCantReadFile , rsrInvalidNumber , rsrNotEnoughNumbers , rsrNotEnoughStrings , rsrInvalidValue ); tReadSyncErrors=array[tReadSyncResult] of string; const cReadSyncErrors:tReadSyncErrors=( 'Нет ошибок.' , 'Неизвестная ошибка.' , 'Не могу открыть файл.' , 'Нет данных или недостаточно данных в файле.' , 'Неверное число или отсутствие числа в файле.' , 'Недостаточно чисел в строке.' , 'Недостаточно строк в файле.' , 'Число вне допустимого диапазона.' ); { считывает синхропосылку из файла aFileName в переменную aSync ФОРМАТ ФАЙЛА: текст Строка, начинающаяся с ";" - комментарий. Может встречаться где угодно. 8 строк с беззнаковыми числовыми значениями от 0 до 255 - синхропосылка для инициализации генератора гаммы. Длина строки не может превышать 255 символовж Пример: ------------- ; Это моя синхропосылка 124 98 35 0 255 ... ------------} function DoReadSync(aFileName:string; var aSync:tDataUnit):tReadSyncResult; { считывает ключ из файла aFileName в переменную aKey ФОРМАТ ФАЙЛА: текст Строка, начинающаяся с ";" - комментарий. Может встречаться где угодно. 16 Строк с беззнаковыми числовыми значениями от 0 до 65535 - ключ. Длина строки не может превышать 255 символовж Пример: ------------- ; Это мой ключ 124 9886 65535 0 1 ... ------------} function DoReadKey(aFileName:string; var aKey:tKey):tReadKeyResult; { считывает таблицу замен из файла aFileName в переменную aSubstTable ФОРМАТ ФАЙЛА: текст Строка, начинающаяся с ";" - комментарий. Может встречаться где угодно. 8 Строк с 16 беззнаковыми числовыми значениями от 0 до 15, разделенными точкой с запятой. Длина строки не может превышать 255 символовж Пример: ------------- ; Это моя таблица замен ; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ;=0 12; 1; 15; 7; 11; 8; 9; 0; 0; 4; 11; 5; 1; 1; 1; 0 ;=1 12; 1; 15; 7; 11; 8; 9; 0; 0; 4; 11; 5; 1; 1; 1; 0 ... ;=7 11; 11; 5; 7; 1; 8; 9; 0; 0; 4; 11; 5; 1; 1; 1; 0 ------------} function DoReadSubstTabl(aFileName:string; var aSubstTable:tBaseSubstitutionTable):tReadSubstTablResult; { Преобразует синхропосылку в строку из 8 8-и битных чисел } function Sync2Str(const aSync:tDataUnit):string; { Преобразует ключ в строку из 16 16-и битных чисел } function Key2Str(const aKey:tKey):string; { Преобразует строку таблицы замен в строку из 16 4-х битных чисел } function SubstTableRow2Str(const aSubstTableRow:tBaseSubstitutionTableRow):string; implementation function SubstTableRow2Str(const aSubstTableRow:tBaseSubstitutionTableRow):string; var i:tBstColNumber; s:string[5]; begin Str(aSubstTableRow[0], result); for i:=Succ(low(i)) to high(i) do begin Str(aSubstTableRow[i], s); if Length(s)<2 then s:=' '+s; result:=result+cSubstTableNumDelimiter+' '+s; end; end; function DoReadSubstTabl(aFileName:string; var aSubstTable:tBaseSubstitutionTable):tReadSubstTablResult; function DoReadSubstTablStr(aStr:string; var aSubstTableRow:tBaseSubstitutionTableRow):tReadSubstTablResult; var c:tBstColNumber; p:word; b:tBstElement; vErr:integer; begin if aStr[LENGTH(aStr)]<>cSubstTableNumDelimiter then aStr:=aStr+cSubstTableNumDelimiter; for c:=low(c) to high(c) do begin p:=Pos(cSubstTableNumDelimiter, aStr); if p>1 then begin Val(Copy(aStr, 1, p-1), b, vErr); if vErr<>0 then begin Result:=rstrInvalidNumber; Exit; end else if (bhigh(b)) then begin Result:=rstrInvalidValue; Exit; end else begin aSubstTableRow[c]:=b; if LENGTH(aStr)>p+1 then begin aStr:=Copy(aStr, p+1, LENGTH(aStr)); end else begin aStr:=''; end; end; end else begin Result:=rstrNotEnoughNumbers; Exit; end; end; Result:=rstrOK; end; var f:text; OldFileMode:byte; r:low(tBstRowNumber)..high(tBstRowNumber)+1; s:string; begin result:=rstrUnknownError; try { Открываем файл } Assign(f,aFileName); OldFileMode:=System.FileMode; System.FileMode:=0; {$IfOpt I+} {$Define IOisON} {$I-} {$EndIf} Reset(f); System.FileMode:=OldFileMode; if IOResult<>0 then begin {$IfDef IOisON} {$UnDef IOisON} {$I+} {$EndIf} Result:=rstrCantOpenFile; Exit; end; { Читаем файл построчно} r:=low(r); while not EOF(f) AND (r0 then begin {$IfDef IOisON} {$UnDef IOisON} {$I+} {$EndIf} Result:=rstrCantReadFile; Close(f); Exit; end; if Length(s)>0 then begin if s[1]<>';' then begin Result:=DoReadSubstTablStr(s, aSubstTable[r]); if Result<>rstrOK then begin Close(f); Exit; end; Inc(r); end; end; end; { Закрываем файл } Close(f); if (r0 then begin {$IfDef IOisON} {$UnDef IOisON} {$I+} {$EndIf} Result:=rsrCantOpenFile; Exit; end; { Читаем файл построчно} i:=low(i); while not EOF(f) AND (i0 then begin {$IfDef IOisON} {$UnDef IOisON} {$I+} {$EndIf} Result:=rsrCantReadFile; Close(f); Exit; end; if Length(s)>0 then begin if s[1]<>';' then begin Val(s, b, vErr); if vErr<>0 then begin Result:=rsrInvalidNumber; Close(f); Exit; end; aSync.Bytes[i]:=b; Inc(i); end; end; end; { Закрываем файл } Close(f); if (i0 then begin {$IfDef IOisON} {$UnDef IOisON} {$I+} {$EndIf} Result:=rkrCantOpenFile; Exit; end; { Читаем файл построчно} i:=low(i); while not EOF(f) AND (i0 then begin {$IfDef IOisON} {$UnDef IOisON} {$I+} {$EndIf} Result:=rkrCantReadFile; Close(f); Exit; end; if Length(s)>0 then begin if s[1]<>';' then begin Val(s, w, vErr); if vErr<>0 then begin Result:=rkrInvalidNumber; Close(f); Exit; end; aKey.Wds[i]:=w; Inc(i); end; end; end; { Закрываем файл } Close(f); if (i