Доброй ночи! У меня большая проблема. Я не могу найти ошибку в программе. Она вместо удваивания пробела пишет их произвольное количество (у меня было их максимум 7), и соответсвенно такой текст никак не расшифровывался. Исходник программы прилагается. Прошу извинения за мои коментарии, если они не верные. Если кто сможет отредактировать исходник до работоспособного состояния то просьба кинуть его на мыло
sss1992@mail.ru.Я рад любой помощи. Буду всем очень признателен))))Заранее спасибо
Задача
Есть некий текст и в нем тоже надо спрятать другой текст. Скрываемый текст разбиваем на биты. И если очередной бит секретного сообщения равен единице, то в тексте-контейнере удваиваем пробел. Если очередной бит скрываемого текста равен нулю, то пробел остается одним. Обычные буквы пропускаются в тексте-контейнере. То есть, для того, чтобы скрыть слово "пиво" (4 буквы, 4 байта или 32 бита), нужен текст-контейнер как минимум, с 32-мя пробелами.
Таким же методом надо расшифровать сообщение обратно.
Delphi |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
| Function DecToBin(Int:Longint):String;
Var
StringConst:String[2];
Begin
StringConst:='01';
Result:='';//Обнуляем результат функции
Repeat
//Если Int Mod 2 = 0(т.е. остаток 0) пишем первый элемент,
//если Int Mod 2 = 1, то второй пишем элемент
Result:=StringConst[(Int Mod 2)+1] + Result;
Int:=Int Div 2;//Делим десятичное число на 2
Until Int=0;
End;
Function BinToDec(Value:String):String;
Var
i:SmallInt;//тип SmallInt это целое число от -32768 до 32767
DecValue:Integer;
Digit:String[2];
Begin
Digit:='01';
DecValue:=0;
For i:=1 To Length(Value) Do
DecValue:=DecValue*2+Pos(Value[i],Digit)-1;
Result:=IntToStr(DecValue);
End;
Function FirstEight(Str:String):String;
Var
i:SmallInt;
Begin
For i:=1 To 8 Do
Result:=Result+Str[i];
End;
Function StrToBin(TextValue:String):String;
Var
TempString:String;
OctString:String;
BinString:String;
i,k:SmallInt;
Begin
For i:=1 To Length(TextValue) Do Begin
TempString:=DecToBin(Ord(TextValue[i]));//переводим i-й элемент в //двоичную систему и присваиваем его TempString
OctString:='';
If Length(TempString)<8 Then Begin//если длина TempString<8
For k:=1 To 8-Length(TempString) Do Begin//то создаем строку
OctString:=OctString+'0';//длиной 8-Length(TempString) состоящую //из нулей
End;
End;
TempString:=OctString+TempString;//дополняем нулями TempSting
BinString:=BinString+TempString;//Записываем все в одну строку
Result:=BinString;//Присваиваем всё функции
End;
End;
procedure TForm1.Button1Click(Sender: TObject);//Кнопка открыть файл
Begin
FileName:='';
OpenDialog1.Filter:='Все файлы (* . *)';
If OpenDialog1.Execute Then
FileName:=OpenDialog1.FileName;
End;
procedure TForm1.Button2Click(Sender: TObject);//Кнопка спрятать текст
Var
i:SmallInt;
k:LongInt;
BinString:String;//Здесь двоичное представление текста сообщения
RecString:String; //Здесь считанная из файла строка
MY_IN_FILE:TextFile; //Файл-контейнер
MY_OUT_FILE:TextFile; //Файл-контейнер с сообщением
Begin
AssignFile(MY_IN_FILE,FileName); //Открываем файл-контейнер и присваиваем ему дескриптор MY_IN_FILE. В переменной FileName имя файла, имя в эту переменную заносится процедурой кнопки Открыть файл
AssignFile(MY_OUT_FILE,'Задание3.txt'); //Создаём файл Задание3.txt в который запишем
//содержимое файла-контейнера и зашифрованное сообщение и присваиваем ему дескриптор MY_OUT_FILE.
Reset(MY_IN_FILE);//Открываем файл-контейнер для чтения
ReWrite(MY_OUT_FILE);//Открываем файл для записи
BinString:=StrToBin(Edit1.Text);//В строке BinString двоичное представление строки введённой в Edit1
k:=1; //Присваиваем k:=1 для того чтобы обрабатывать BinString с первого символа
While Not Eof(MY_IN_FILE) Do //До конца файла контейнера
Begin
ReadLn(MY_IN_FILE,RecString);//Читаем одну строчку из файла
For i:=1 To Length(RecString) Do//Перебираем символы этой строчки
Begin
If RecString[i]=' ' Then//Если встретился пробел
Begin
// то проверяем чему равен очередной бит скрываемой информации
Case BinString[k] Of
'1':Insert(' ',RecString,i+1);//Если бит равен 1 то после пробела пишем пробел
'0':Insert('',RecString,i+1);//Если бит равен 0 то ничего не пишем
End;
Inc(k);//Увеличиваем k на 1 чтобы обработать следущий бит информации
End;
End;
WriteLn(MY_OUT_FILE,RecString); //Записываем обработанную строку в файл
End;
CloseFile(MY_OUT_FILE); //Закрываем файл-контейнер
CloseFile(MY_IN_FILE); //Закрываем файл-контейнер с спрятанным сообщением
ShowMessage('Строка спрятана'); //Выводим сообщение о завершении работы
End;
procedure TForm1.Button3Click(Sender: TObject);//Кнопка извлечь текст
Var//Назначение переменных аналогично как и задании 2
i,k:SmallInt;
TempString:String;
DecString:String;
BinString:String;
RecString:String;
MY_DECRYPT:TextFile;
Begin
AssignFile(MY_DECRYPT,FileName);//Открываем файл-контейнер с сообщением и
//присваиваем ему дескриптор MY_DECRYPT. В переменной FileName имя файла,
//имя в эту переменную заносится процедурой кнопки Открыть файл
Reset(MY_DECRYPT);//Открываем файл для чтения
While Not Eof(MY_DECRYPT) Do//Пока не конец файла то
Begin
ReadLn(MY_DECRYPT,RecString);//Читаем одну строчку из файла
For i:=1 To Length(RecString) Do//С каждым элементом строки
Begin
k:=i+1;//Индекс k будет у следущего за i-м символа
If(RecString[i]=' ') And (RecString[k]=' ') Then BinString:=BinString+'1';
//Если встретились два пробела то в BinString пишем 1
If(RecString[i]=' ') And (RecString[k]<>' ') Then BinString:=BinString+'0';
//Если встретились только один пробел то в BinString пишем 0
End;
End;
For i:=0 To Trunc(Length(BinString) Div 8) Do //т.к. число полных байтов в строке BinString будет
//Trunc(Length(BinString) Div 8).Функция Trunc отбрасывает дробную часть от числа.
//Делим на 8 т.к. в 1 байт = 8 бит
Begin
TempString:=FirstEight(BinString);//Записываем в строку TempString первые 8 символов
DecString:=DecString+Chr(StrToInt(BinToDec(FirstEight(BinString)))); //Переводим число записанное в TempString(это двоичное число) в десятичное и
//записываем в DecString символ соответствующий этому числу
If Chr(StrToInt(BinToDec(FirstEight(BinString))))=#0 Then Break;
//Если символы в сообщении закончились то выходим из цикла
Delete(BinString,1,8);//Удаляем первые 8 символов стобы был доступен следущий символ
End;
ShowMessage('Строка расшифрована');
Edit1.Text:=DecString;//Записываем результат в Edit
CloseFile(MY_DECRYPT);//Закрываем файл
End; |
|