Кодирование стего знаками совпадающего начертания.
program StegoChange;
(***************************************************************)
(* Простая стеганографическая программа для работы с *)
(* русскими текстами основанная на частичной замене русских *)
(* символов латинскими одинакового с ними начертания. *)
(* мспользует от 1 до 3 параметров, которые и определяют *)
(* выполняемую программой функцию. При этом первый из *)
(* параметров всегда представляет файл-контейнер. *)
(* Если этот параметр единственный, то проверяется *)
(* наличие стеганограммы в файле-контейнере с выводом *)
(* результата на экран. По сути это режим стеганодетектора. *)
(* Если таких параметров два, стеганограмма извлекается из *)
(* контейнера, а результат записывается в заданный вторым *)
(* параметром файл. *)
(* Наконец, если используются все три параметра, то *)
(* стеганографический текст из файла заданного вторым *)
(* параметром, упрятывается в файл-контейнер, заданный первым *)
(* параметром, а результат стеганографического преобразования *)
(* записывается в файл, заданный третьим параметром. *)
(* Совпадение двух имён файлов допускается (трёх - абсурд). *)
(* Литература: О.Шарапов. Программная русификация *)
(* матричных принтеров. //Монитор. - 1993, #3, стр. 48..57. *)
(***************************************************************)
type
StringType = string [$FF];
Index = (Rus, Lat);
SetOfChar = set of char;
const
TempName = '$$$$$$$$.$$$';
Max = 13;
Key1 = $1234;
Key2 = $4567;
Tab : array [Index, 1..22] of char = ('ВЕКМНРСТХаеосАОикпрту'#32,
'BEKMHPCTXaeocAOuknpmy'#00);
var
F, G, H : text;
X : StringType;
I, J : integer;
K, L : byte;
C, CC : char;
LatSet : SetOfChar;
CharSet : SetOfChar;
LargeLat : SetOfChar;
LargeChar : SetOfChar;
Count : real;
begin
LowVideo;
if not (ParamCount in [1..3])
then
begin
WriteLn ('Ожидается от 1 до 3 параметров:');
WriteLn ('1 - вывод стеганограммы на экран;');
WriteLn ('2 - вывод стеганограммы в файл;');
WriteLn ('3 - запись стеганограммы в файл.');
Exit
end;
Assign (F, ParamStr (1));
Reset (F);
Count := 0;
MemW [Dseg : $01FE] := Key1;
MemW [Dseg : $01FC] := Key2;
L := 0;
LatSet := [];
CharSet := [];
for I := 1 to Max
do
begin
LatSet := LatSet + [Tab [Lat, I]];
CharSet := CharSet + [Tab [Rus, I]] + [Tab [Lat, I]]
end;
LargeLat := LatSet;
LargeChar := CharSet;
for I := Succ (Max) to 21
do
begin
LargeLat := LargeLat + [Tab [Lat, I]];
LargeChar := LargeChar + [Tab [Lat, I]] + [Tab [Rus, I]]
end;
(*---------------------ВЫВОД СТЕГАНОГРАММЫ НА ЭКРАН--------------------*)
if ParamCount = 1
then
begin
while not Eof (F)
do
begin
ReadLn (F, X);
for I := 1 to Length (X)
do
begin
J := 1;
C := X [I];
if C in LargeChar
then
begin
K := K shl 1;
if C in LargeLat
then K := K or 1;
L := Succ (L) mod 8;
if L = 0
then Write (Chr (K))
end;
end
end;
Close (F);
if WhereX <> 1
then WriteLn;
WriteLn ('Ok!');
Exit
end;
(*----------------------ВЫВОД СТЕГАНОГРАММЫ В ФАЙЛ---------------------*)
if ParamCount = 2
then
begin
if Pos (':', ParamStr (2)) <> 2
then Assign (G, TempName)
else Assign (G, Copy (ParamStr (2), 1, 2) + TempName);
Assign (G, TempName);
Rewrite (G);
while not Eof (F)
do
begin
ReadLn (F, X);
for I := 1 to Length (X)
do
begin
J := 1;
C := X [I];
if C in CharSet
then
begin
K := K shl 1;
if C in LatSet
then K := K or 1;
L := Succ (L) mod 8;
if L = 0
then
begin
Count := Count + 1;
K := K xor Random (256);
Write (Chr (K));
Write (G, Chr (K))
end
end;
end
end;
Close (F);
Close (G);
Assign (F, ParamStr (2));
(*$I-*)
Erase (F);
(*$I+*)
I := IoResult;
Rename (G, ParamStr (2));
if WhereX <> 1
then WriteLn;
WriteLn ('Прочитано ', Count : 0 : 0, ' байт стего...');
Exit
end;
(*----------------------ЗАПмСЬ СТЕГАНОГРАММЫ В ФАЙЛ--------------------*)
Assign (G, ParamStr (2));
if Pos (':', ParamStr (3)) <> 2
then Assign (H, TempName)
else Assign (H, Copy (ParamStr (3), 1, 2) + TempName);
Reset (G);
Rewrite (H);
while not Eof (F)
do
begin
ReadLn (F, X);
for I := 1 to Length (X)
do
begin
J := 1;
C := X [I];
while (J <= Max) and (C <> Tab [Rus, J])
and (C <> Tab [Lat, J])
do J := Succ (J);
if J <= Max
then
begin
if L = 0
then
begin
if Eof (G)
then CC := #00
else Read (G, CC);
Count := Count + 1;
Write (CC);
K := Ord (CC) xor Random (256)
end;
if K and $80 <> 0
then X [I] := Tab [Lat, J]
else X [I] := Tab [Rus, J];
K := K shl 1;
L := Succ (L) mod 8
end
end;
WriteLn (H, X)
end;
Close (F);
Close (G);
Close (H);
Assign (F, ParamStr (3));
(*$I-*)
Erase (F);
(*$I+*)
I := IoResult;
Rename (H, ParamStr (3));
if WhereX <> 1
then WriteLn;
if (Count <> 0) and (L <> 0)
then Count := Count - 1;
WriteLn ('Записано ', Count : 0 : 0, ' байт стего...');
Exit
end.