S9
Волшебник
656 / 259 / 88
Регистрация: 18.12.2010
Сообщений: 545
1

Стеганография

01.04.2011, 08:30. Показов 86839. Ответов 70
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Основы и методы защиты информации
Для некоторых скрытие текста методами стеганографии вызывает некоторые трудности,
поэтому я решил написать небольшую статью где подробно изложу ход выполнения
практических заданий. Если кому-нибудь это покажется банально просто то просьба не читать,
эта статья рассчитана на людей кто хочет выполнить практические задания по «Основы и методы
защиты информации» обладая базовыми знаниями в программировании. Для начала приведу
тексты самих заданий.
Задание 1. Нужно посчитать контрольную сумму от файла, используя любой из
алгоритмов подсчета контрольных сумм.
Задание 2. Есть текст и в нем надо скрыть некоторую фразу, состоящую из букв. Буквы
этой фразы представляются как байты. Эти байты надо разбить на биты.
Текст, в котором будет прятаться сообщение, должен иметь много строчек (как
стихотворение). Мы должны разбить скрываемый текст на биты. И если очередной бит
скрываемой информации равен единице, то в конец очередной строки текста-контейнера
дописываем пробел. Если же бит равен нулю, то в конец строки не пишем пробел.
После шифрования, шифровку надо будет обратно раскодировать.
Задание 3. Есть некий текст и в нем тоже надо спрятать другой текст. Аналогичным
образом скрываемый текст разбиваем на биты. И если очередной бит секретного сообщения
равен единице, то в тексте-контейнере удваиваем пробел. Если очередной бит скрываемого
текста равен нулю, то пробел остается одним. Обычные буквы пропускаются в тексте-
контейнере. То есть, для того, чтобы скрыть слово "пиво" (4 буквы, 4 байта или 32 бита), нужен
текст-контейнер как минимум, с 32-мя пробелами.
Таким же методом надо расшифровать сообщение обратно.
Задание 4. условие то же, что и в задаче 3. Только если бит секретного сообщения равен
единице, то в тексте-контейнере меняем русскую букву на английский аналог. Если бит равен
нулю, то очередную букву-аналог в тексте-контейнере оставляем без изменений. Буквы-аналоги -
это буквы русского языка, имеющие аналогичное начертание в англ. языке.
Так же, надо расшифровать текст обратно.
З.Ы: все примеры реализованы в Delphi 7
Задание 1. Это задание на мой взгляд является самым простым.
Тут следующими переменными будет обозначено
TEST_FILE:File Of Byte; //Файл, контрольную сумму которого будем считать
CS:Byte;//Сюда будет считан очередной байт из файла
Res:Integer;//Здесь будет конечный результат
Sum:Integer;//Здесь будет контрольная сумма
Простейшим способом подсчета КС файла служит следующий алгоритм:
1)Обнулить переменную контрольной суммы Sum
2)Пока не конец файла
a.Считать очередной байт
б.Прибавить его к контрольной сумме
Найти остаток от деления Sum на некое большое целое число.
Согласно алгоритму обнуляем Sum;
Sum:=0;
Далее запускаем цикл
While Not Eof(TEST_FILE) Do Begin//Пока не конец файла
Read(TEST_FILE,CS);//Читаем один байт из файла
Sum:=Sum+CS;//Прибавляем этот байт к контрольной сумме
End;
Т.к. контрольная сумма может получится достаточно большой то
делим результат на какое-нибудь большое число, например 10000.
Res:=Sum Mod 10000;
В переменной Res наш конечный результат, его и выводим на экран любым способом.
Вот весь текст процедур.Форма состояла из 1 Memo, 1 OpenDialog и 2 SpeedButton
Файл TEST_FILE лучше объявить в разделе глобальных переменных
(перед implementation),т.к. файл используется в двух процедурах

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
var
TEST_FILE:File Of Byte;//Это файл контрольную сумму которого будем
//считать
 
Procedure TForm1.SpeedButton1Click(Sender: TObject);
Begin
Memo1.Lines.Clear;//Очищаем поле
OpenDialog1.Filter:='Все файлы ( *.* )';
If OpenDialog1.Execute Then
AssignFile(TEST_FILE,OpenDialog1.FileName);//Связываем дескриптор
// TEST_FILE с именем файла
End;
Procedure TForm1.SpeedButton2Click(Sender: TObject);
Var
CS:Byte;
Res:Integer;//Здесь будет конечный результат
Sum:Integer;//Здесь будет контрольная сумма
Begin
Sum:=0;//Обнуляем контрольную сумму
Reset(TEST_FILE);//Открываем файл для чтения
While Not Eof(TEST_FILE) Do Begin//Пока не конец файла
Read(TEST_FILE,CS);//Читаем один байт из файла
Sum:=Sum+CS;//Прибавляем этот байт к контрольной сумме
End;
Res:=Sum Mod 10000;//Делим полученный результат на достаточно большое
//число
//т.к. контрольная сумма файла может быть очень большой
Memo1.Lines.Text:=IntToStr(Res);//Выводим результат
CloseFile(TEST_FILE);
End;
Задание 2. Алгоритм выполнения написан непосредственно в задании
Это задание (как и следущие два) будет состоять из двух подзаданий: скрытие строки и
извлечение строки.
Для этих заданий нам понадобятся следущие функции, которые мы и напишем.
DecToBin (Перевод из десятичной системы в двоичную)
BinToDec(Перевод из двоичной в десятичную)
StrToBin (Перевод из строки в биты)
FirstEight(Будет возвращать первые 8 символов строки)
DecToBin
Работает эта функция следущим образом. Известно что в Pascal нумерация элементов
строки начинается с 1 и поэтому если остаток от деления на 2 равен 1 (при переводе из
десятичной в двоичную делением столбиком на 2) то пишем второй элемент строки StringConst,
т.е. пишем 1, если остаток ноль то пишем первый элемент(пишем 0).
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
{ конец функции DecToBin }
BinToDec
Как видно из названия это противоположенность предыдущей функции, она переводит из
двоичной в десятичную. Тут тоже всё просто. От начала и до конца строки к произведению
DecValue*2 (DecValue это десятичное значение) прибавляем 1 или 0 взавмсимости от элемента
строки Value (это строка где содержится двоичное число) . Если элемент ноль то, то его позиция
в строке Digit равна 1, если элемент 1 – позиция в Digit равна 2. Но исходная система двоичная,
поэтому вычитаем 1. И так всё происходит до конца цикла, и в итоге в DecValue получается
десятичное число. Далее переводим его в строку функцией IntToStr и присваиваем результату
функции. Вот текст функции.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
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;
{ конец функции BinToDec }
StrToBin
Эта хитрая функция переводит строку в биты( набор нулей и едениц ).
Работает всё следущим образом.
Мы каждый элемент переводим в двоичное представление (для этого мы написали ранее
функцию DecToBin ). Для этого возвращаем числовое представление i-го элемента функцией
Ord. Например если Chr(100) это соответствует символу ‘d’ то Ord(‘d’) = 100. Далее переводим
это число в двоичное функцией DecToBin и присваиваем его строке TempString. Длина этой
строки может быть от 1 до 8(т.к. один символ занимает 1 байт, а 1 байт это 8 бит) и этого совсем
не надо. Поэтому надо дополнить (если это требуется) каждую строку нулями до 8 символов. Для
этого надо создать строку длиной 8-Length(TempString) состоящую из нулей, и дополнить ею
строку TempString. И эту строку добавляем в строку BinString.Таким образом выполяем цикл
пока не закончится элементы строки TextValue.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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;
{Конец функции StrToBin }
FirstEight
Эта функция самая простая из всех. Она возвращает первые 8 символов строки.
Принцип работы очевиден: считывает первые 8 символов и присваивает их результату
функции.
Delphi
1
2
3
4
5
6
7
8
Function FirstEight(Str:String):String;
Var
i:SmallInt;
Begin
For i:=1 To 8 Do
Result:=Result+Str[i];
End;
{Конец функции FirstEight }
Теперь собственно само задание. Оно состоит из двух частей скрытие и извлечение строки. Сначала
кинем на форму 3 кнопки, 1 OpenDialog (находится он на вкладке Dialog) и 1Edit. Кнопки можно назвать
Открыть файл, Спрятать текст и Извлечь текст. Работать программа будет так: сначала открываем файл-
контейнер (это файл куда будем прятать сообщение, он должен содержать минимум 8*n строк, где n –
число символов в сообщении ), далее вводим в Edit своё сообщение и жмем Скрыть текст, в папке с
программой должен появиться файл Задание2.txt. В этом файле и храниться наше сообщение. Потом
кликаем Открыть файл и выбираем файл с сообщением (Задание2.txt) и нажимаем Извлечь текст, и в Edit1
должно появиться сообщение.

Открыть файл.
Этот код будем выполняться при нажатии на кнопку Открыть файл
Delphi
1
2
3
4
5
6
7
8
9
//переменную FileName объявляем глобальной, т.е. перед Implementation
//суть этой процедуры в том чтобы в переменную FileName ввести имя
//файла-контейнера
Begin
FileName:=’’;
OpenDialog1.Filter:='Все файлы (* . *)';
If OpenDialog1.Execute Then
FileName:=OpenDialog1.FileName;
End;
Часть 1. Скрытие сообщения.
Этот код будем выполняться при нажатии на кнопку Скрыть текст
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
Var
i:SmallInt;
MY_IN_FILE:TextFile;//Это файл-контейнер
MY_OUT_FILE:TextFile;//Это файл-контейнер с зашифрованным сообщением
RecString:String;
BinString:String;
Begin
Try //от Try до Except перехватываем ошибки
RecString:=’’;
BinString:=StrToBin(Edit1.Text);//переводим содержимое Edit1
//в двоичное представление и записываем результат в строку BinString
AssignFile(MY_IN_FILE,FileName);//Связываем дескриптор MY_IN_FILE с
//файлом контейнером
AssignFile(MY_OUT_FILE,’Задание2.txt);//Создаем файл Задание2.txt с
//дескриптором MY_OUT_FILE
Reset(MY_IN_FILE);//Открываем MY_IN_FILE для чтения
ReWrite(MY_OUT_FILE);//Открываем файл MY_OUT_FILE для записи
i:=1;
While Not Eof(MY_IN_FILE) Do //Пока не закончится файл-контейнер
Begin
ReadLn(MY_IN_FILE,RecString);//Читаем одну строку из файла
If BinString[i]='1' Then//если очередной бит сообщения равен 1 то
Insert(' ',RecString,Length(RecString)+1);//в конец строки вставляем
//пробел, а если бит равен 0 то условие не выполняется и пробел
//соответственно не вставляется
WriteLn(MY_OUT_FILE,RecString);//Записываем считанную строку в файл
Inc(i); //Увеличиваем i на 1, чтобы обработать следущий бит сообщения
End;
CloseFile(MY_IN_FILE); //Закрываем файл-контейнер
CloseFile(MY_OUT_FILE); //Закрываем файл с сообщением
MessageDlg('Все прошло гут!',mtInformation, [mbOK], 0);//Выводим
сообщение о //выполнении
Except //если произошла ошибка то выводим сообщение
MessageDlg('Произошла ошибка',mtError, [mbOK], 0);
End;
End;
Часть 2. Извлечение текста.
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
Var
TempString:String;
OutString:String;//Здесь будет текст сообщения
RecString:String; //Здесь будет считанная из файла строка
BinString:String;
DecValue,i,j:SmallInt;
MY_DECRYPT:TextFile;//Файл-контейнер с сообщением
Begin
Try//От Try до Except перехватываем ошибки и обрабатываем их
AssignFile(MY_DECRYPT,FileName);//Открываем файл-контейнер с сообщением
//и присваиваем ему дескриптор MY_DECRYPT. В переменной FileName имя файла,
//имя в эту переменную заносится процедурой кнопки Открыть файл
Reset(MY_DECRYPT); //Открываем файл для чтения
While Not Eof(MY_DECRYPT) Do//До конца файла
Begin
ReadLn(MY_DECRYPT,RecString); //Читаем одну строчку из файла
If RecString[Length(RecString)]=' ' Then//Если последний символ в
//строке пробел то в BinString записываем 1, иначе записываем 0
BinString:=BinString+'1' Else BinString:=BinString+'0';
End;
For i:=0 To Trunc(Length(BinString) Div 8) Do//т.к. число полных
//байтов в строке BinString будет Trunc(Length(BinString) Div 8).Функция
//Trunc отбрасывает дробную часть от числа
Begin
TempString:=FirstEight(BinString);//Записываем в строку TempString
//первые 8 элементов строки BinString ( каждый элемент строки соответствует
//1 биту сообщения
OutString:= OutString+Chr(StrToInt(BinToDec(TempString)));
//В строке OutString будет текст сообщения. Этого добиваемся следущим
//образом. Переводим в десятичную систему TempString(в ней первые 8
//символов,т.е. первая буква сообщения),это число(пока оно типа String)
//переводим в Integer(теперь число является числом, а не строкой) и функцией
//Chr ставим букву соответствующую этому числу. Все расшифрованные буквы
//записываем в строку OutString. Теперь в OutString находится наше сообщение
If Chr(StrToInt(BinToDec(FirstEight(BinString))))=#0 Then Break;
//Если закончились символы в строке (#0 или Chr(0) это означает
//что вообще ничего нет, а не пробел или ноль) то выходим из цикла
Delete(BinString,1,8);//Удаляем из строки первые 8 символов, чтобы
//можно было расшифровать следущюю букву сообщения
End;
Edit1.Text:=OutString;//Записываем в Edit1 расшифрованное сообщение
ShowMessage('Строка успешно расшифрована');
CloseFile(MY_DECRYPT);//Закрываем файл
Except//Если произошла ошибка то выводим сообщение
ShowMessage('Невозможно расшифровать строку');
End;
End;
Задание 3. Тут также алгоритм такой же как и в задании 2.
Задание также будет состоять из двух подзаданий: скрытие и извлечение строки.
Также будет использоваться все функции описанные в задании 2. Форма приложения будет
такая же (3 кнопки, 1 Edit и 1 OpenDialog ). Можно назвать их также как и задании 2.
Обработчик нажатия кнопки Открыть файл такой же.
Весь прикол задания заключается вставкой пробела между слов. Вставляет одну строку в
другую функция Insert.Вставлять пробел между слов будет следущая конструкция:
If RecString[i]=’ ’ Then Insert(’ ’,RecString,i);
Здесь мы вставляем на позицию i в строке RecString строку ’ ’,тобиш пробел.
При расшифровке всё ещё проще: Если встретились два пробела то пишем 1,иначе пишем
ноль.
If(RecString[i]=’ ’) And (RecString[i+1]=’ ’) Then Bin:=Bin+’1’;
If(RecString[i]=’ ’) And (RecString[i+1]<>’ ’) Then Bin:=Bin+’0’;
Это естественно делается в цикле. Вот и все хитрости)

Часть 1. Скрытие текста.
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
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 то перед пробелом пишем
//пробел
'0':Insert('',RecString,i);//Если бит равен 0 то ничего не пишем
End;
Inc(k);//Увеличиваем k на 1 чтобы обработать следущий бит информации
End;
End;
WriteLn(MY_OUT_FILE,RecString); //Записываем обработанную строку в файл
End;
CloseFile(MY_OUT_FILE); //Закрываем файл-контейнер
CloseFile(MY_IN_FILE); //Закрываем файл-контейнер с спрятанным
//сообщением
ShowMessage('Строка спрятана'); //Выводим сообщение о завершении работы
End;
Часть 2. Извлечение текста.
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
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;
Задание 4. Условие то же, что и в задаче 3. Только если бит секретного сообщения
равен единице, то в тексте-контейнере меняем русскую букву на английский аналог. Если бит
равен нулю, то очередную букву-аналог в тексте-контейнере оставляем без изменений. Буквы-
аналоги - это буквы русского языка, имеющие аналогичное начертание в англ. языке. Задание
довольно просто выполнить применив функции из Задания 2 (DecToBin, BinToDec, StrToBin и
FirstEight).
Форма приложения может быть такая же как и в предыдущих заданиях. Кнопка Открыть
файл выполняет тоже самое что и задании 2 или задании 3, поэтому можно тупо скопировать код
из задания 2 или 3.

Часть 1. Скрытие сообщения.
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
Var
i:SmallInt;
k:LongInt;
Bin:String;//Здесь будет сообщение в двоичном виде
Rec:String;
IN_FILE:TextFile;//Файл-контейнер
OUT_FILE:TextFile;// Файл-контейнер с спрятанным сообщением
Begin
Try//От Try до Except ловим ошибки
AssignFile(IN_FILE,FileName); //Присваиваем файлу-контейнеру
//дескриптор MY_IN_FILE. В переменной FileName имя файла, имя в эту
//переменную заносится процедурой кнопки Открыть файл
AssignFile(OUT_FILE,'Задание4.txt');//Создаём файл Задание4.txt в который
//запишем содержимое файла-контейнера и зашифрованное сообщение и
//присваиваем ему дескриптор MY_OUT_FILE.
Reset(IN_FILE);//Открываем файл-контейнер для чтения
ReWrite(OUT_FILE);//Открываем файл-контейнер для записи
Bin:=StrToBin(Edit1.Text);//Функцией StrToBin переводим содержимое
//Edit1 в двоичный символы и записываем результат в строку Bin
k:=1;
While Not Eof(IN_FILE) Do//Если не конец файла то
Begin
ReadLn(IN_FILE,Rec);//Читаем одну строку
For i:=1 To Length(Rec) Do//Обрабатываем в ней каждый символ
Begin
If ((Rec[i]='е')//если i-й символ имеет английский аналог то
Or (Rec[i]='а')
Or (Rec[i]='о') //оператор Or это логическое ИЛИ, т.е. нам достаточно
Or (Rec[i]='А') //чтобы Rec[i] соответствовал хотя бы одному
Or (Rec[i]='Е') //символу из этого списка (е,а,о,с,р или х) в любом
Or (Rec[i]='О') //регистре, и условие будет выполнятся
Or (Rec[i]='с')
Or (Rec[i]='р')
Or (Rec[i]='х')
Or (Rec[i]='С')
Or (Rec[i]='Р')
Or (Rec[i]='Х')) Then
Begin
If Bin[k]='1' Then//Если k-ый элемент строки Bin равен ’1’ то
Begin//меняем русскую букву в i-ом элементе строки Rec на такую же по
//написанию английскую
If Rec[i]='е' Then Rec[i]:='e'; //Rus->Eng
If Rec[i]='а' Then Rec[i]:='a';
If Rec[i]='о' Then Rec[i]:='o';
If Rec[i]='Е' Then Rec[i]:='E';
If Rec[i]='А' Then Rec[i]:='A';
If Rec[i]='О' Then Rec[i]:='O';
If Rec[i]='с' Then Rec[i]:='c';
If Rec[i]='р' Then Rec[i]:='p';
If Rec[i]='х' Then Rec[i]:='x';
If Rec[i]='С' Then Rec[i]:='E';
If Rec[i]='Р' Then Rec[i]:='C';
If Rec[i]='Х' Then Rec[i]:='X';
End;
Inc(k); //Производим инкремент k (увеличения на 1),чтобы был доступен
//следущий бит сообщения
End;
End;
WriteLn(OUT_FILE,Rec); //Записываем полученную строку в файл-контейнер
//с сообщением
End;
CloseFile(OUT_FILE); //Закрываем файлы которые использовали
CloseFile(IN_FILE);
MessageDlg('Строка спрятана',mtInformation, [mbOK], 0);//Выводим
//сообщение о выполнении работы
Except//Если возникла ошибка то
ShowMessage('Произошла ошибка'); //Выводим соответствущее сообщение
End;
Часть 2. Извлечение сообщения.
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
Var
i:Smallint;
Temp:String;
Res:String; //Здесь будет расшифрованный текст сообщения
Bin:String;
Rec:String;
DECRYPT:Textfile;//Файл-контейнер со спрятанным сообщением
Begin
Try//От Try до Except ловим ошибки
Assignfile(DECRYPT,Filename);//Открываем файл-контейнер с сообщением
//и присваиваем ему дескриптор MY_DECRYPT. В переменной FileName имя файла,
//имя в эту переменную заносится процедурой OnClick кнопки Открыть файл
Reset(DECRYPT);//Открываем файл для чтения
Bin:='';
While Not Eof(DECRYPT) Do
Begin
Readln(DECRYPT,Rec);//Читаем из файла одну строчку
For i:=1 To Length(Rec) Do//Обрабатываем каждый символ этой строчки
Begin
Case Rec[i] Of //Если i-ый символ считанной строки является
//буквой-аналогом то взависимости от буквы пишем в строку Bin '0' или
//'1'(если буква английская то пишем '1', а если русская – то пишем '0'
'E':Bin:=Bin+'1';//Здесь английские буквы
'A':Bin:=Bin+'1';
'O':Bin:=Bin+'1';
'A':Bin:=Bin+'1';
'E':Bin:=Bin+'1';
'O':Bin:=Bin+'1';
'C':Bin:=Bin+'1';
'P':Bin:=Bin+'1';
'X':Bin:=Bin+'1';
'C':Bin:=Bin+'1';
'P':Bin:=Bin+'1';
'X':Bin:=Bin+'1';
'Е':Bin:=Bin+'0';//Здесь русские буквы
'А':Bin:=Bin+'0';
'О':Bin:=Bin+'0';
'А':Bin:=Bin+'0';
'Е':Bin:=Bin+'0';
'О':Bin:=Bin+'0';
'С':Bin:=Bin+'0';
'Р':Bin:=Bin+'0';
'Х':Bin:=Bin+'0';
'С':Bin:=Bin+'0';
'Р':Bin:=Bin+'0';
'Х':Bin:=Bin+'0';
End;
End;
End;
For i:=0 To Trunc(Length(BinString) Div 8) Do//т.к. число полных
//байтов в строке BinString будет Trunc(Length(BinString) Div 8).Функция
//Trunc отбрасывает дробную часть от числа
Begin
Temp:=Firsteight(Bin);//Читаем первые 8 символов из строки Bin
Listbox1.Items.Add(Temp+' '+Chr(Strtoint(Bintodec(Firsteight(Bin)))));
If Temp='00000000' Then Break;//Если считанный символ Chr(0) то это
//значит что сообщение закончилось и поэтому мы выводим из цикла
Temp:='';
Res:=Res+Chr(Strtoint(Bintodec(Firsteight(Bin))));
Delete(Bin,1,8); //Удаляем из строки Bin первые 8 символов, чтобы
//обработать следущие 8
End;
ShowMessage('Строка расшифрована');//Выводим сообщение о окончании
//работы
Edit1.Text:=Res;//Записываем в Edit1 результат расшифровки
Closefile(DECRYPT);//Закрываем файл
Except//Если возникла ошибка то
ShowMessage('Какая-то ошибка...');//Выводим сообщение
End;
End;
Вот собственно и всё Я эти задания сдал и у меня все норм. надеюсь у вас будет также все гут
Вложения
Тип файла: rar S9.rar (1.03 Мб, 579 просмотров)
23
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.04.2011, 08:30
Ответы с готовыми решениями:

Стеганография
Доброго времени суток. Я начал изучать основы стеганографии и столкнулся с проблемой. Необходимо...

Стеганография
Доброй ночи! У меня большая проблема. Я не могу найти ошибку в программе. Она вместо удваивания...

Стеганография.Шифрование текста в картинку
Задали курсовую Стеганография, нужно чтобы текст шифровался в картинку jpeg. Помогите пожалуйста....

Стеганография LSB BMP
Такой вопрос: мне нужно из едита побитно запихнуть в байты цвета файла-контейнера биты текста. Есть...

70
S9
Волшебник
656 / 259 / 88
Регистрация: 18.12.2010
Сообщений: 545
09.07.2011, 20:41  [ТС] 2
Хотел предложить ещё один вариант решения данных задач с использованием побитовых операций. Преимущество - отпадет необходимость переводить сообщение в двоичный вид.
Весь код прокомментирован, а суть заданий изложена в предыдущем посте.
Задание 2

----------------------------------------------- СОКРЫТИЕ ------------------------------------------------
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
Var
   BAG,OUT_FILE:TextFile;//в BAG – файл-контейнер, а в OUT_FILE – будет результат(т.е. файл-контейнер с сообщением
   Cell,i,j:Byte;
   Messg,s:String; //В Messg – сообщение, которое надо спрятать
Begin
  Messg:=Memo1.Text;//Записываем содержимое Memo в строку Messg 
  OpenDialog1.Filter:='Текстовые файлы';
If OpenDialog1.Execute Then//Если диалоговое окно активировано, то
  Begin
  AssignFile(BAG,OpenDialog1.FileName);//Связываем с BAG файл, который выбрали в OpenDiаlog
  Reset(BAG);//Открываем его для чтения
  AssignFile(OUT_FILE,'Результат задания 2.txt');
  ReWrite(OUT_FILE);//Создаем и открываем для записи файл-контейнер с сообщением
  For i:=1 To Length(Messg) Do//С каждым элементом строки Messg делаем следующее
    Begin
      Cell:=Ord(Messg[i]); //Переводим букву с число(следует помнить, что буквы – это цифры от 0 до 255.См. таблицу ASCII
      For j:=1 To 8 Do//т.к. в 1 байт = 8 бит, то обрабатываем каждый бит сообщения, т.е. не совсем сообщения, а буквы сообщения
        Begin
          ReadLn(BAG,s);//Считываем строку из файла-контейнера
          If Cell And 1 = 1 Then//Если текущий бит сообщения равен 1 то
            s:=s + ' ';//добавляем к строке пробел
          WriteLn(OUT_FILE,s);//И записываем в результирующий файл
          Cell:=Cell Shr 1;//Сдвигаемся вправо на 1 бит
        End;
    End;
  Form1.Caption:='Успешно спрятано';//Выводим сообщение, что все сделали
  End
Else//Если файл при открытии диалога не был выбран, то выводим соответствующее сообщение 
  Form1.Caption:='Не выбран файл-контейнер...';
If Not Eof(BAG) Then//Если остались строки в файле-контейнере, то
    While Not Eof(BAG) Do//Остаток файла копируем в файл-контейнер с сообщением (т.е. OUT_FILE)
      Begin
        If Eof(BAG) Then Break;
          ReadLn(BAG,s);
          WriteLn(OUT_FILE,s);
      End;
 
  CloseFile(BAG);//Закрываем файлы, которые открыли
  CloseFile(OUT_FILE);
End;
--------------------------------------------- ИЗВЛЕЧЕНИЕ ----------------------------------------------
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
Var
  DECRYPT:TextFile;// Файл с сообщением
  i,cell:Byte;
  s:String;
Begin
  OpenDialog1.Filter:='Открыть файл-контейнер';
  OpenDialog1.Execute;
  AssignFile(DECRYPT,OpenDialog1.FileName);
  Reset(DECRYPT);
 
  While Not Eof(DECRYPT) Do//Продолжаем цикл, пока не конец файла
    Begin
      cell:=0;//Здесь будет расшифрованная буква
      For i:=1 To 8 Do//Собственно расшифровываем очередную букву сообщения
        Begin
          cell:=cell Shr 1;//Сдвигаемся на 1 разряд вправо
          ReadLn(DECRYPT,s);//Считали из файла строку и записали её в s
          If s[Length(s)] = ' ' Then//Если последний символ пробел, то
            cell:=cell Or 128;//Добавляем 1 в соотвествущий разряд
//почему 128 – потому что 128 = 1000 0000 в двоичном коде, и поэтому при первом вызове cell:=cell Or 128 добавим в старший разряд 1, если не вызывается cell:=cell Or 128 (выражение s[Length(s)] = ' ' ложно) то записывается 0(т.к. в начале цикла сдвигаем на 1 разряд вправо конструкцией cell:=cell Shr 1).  
        End;//В итоге после 8 итераций цикла в cell будет расшифрованная буква
        Memo1.Text:=Memo1.Text + Chr(cell);//Записываем эту букву в Memo
    End;
    CloseFile(DECRYPT);
End;
Задание 3

----------------------------------------------- СОКРЫТИЕ ------------------------------------------------
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
Var
  BAG,OUT_FILE:File Of Byte;//Т.к. описание большинства конструкций бало произведено в предыдущем задании, то я их описывать не буду.
  Messg:String;
  i,j:Integer;
  b,cell:Byte;
Begin
  OpenDialog1.Filter:='Текстовые файлы';
  IF OpenDialog1.Execute Then
    Begin
      AssignFile(BAG,OpenDialog1.FileName);
      Reset(BAG);
      AssignFile(OUT_FILE,'Результат задания 3.txt');
      ReWrite(OUT_FILE);
      Messg:=Memo1.Text;
      For i:=0 To Length(Messg) Do
        Begin
          Cell:=Ord(Messg[i]);
            For j:=1 To 8 Do
              Begin
              If Eof(BAG) Then Break;//Если встретили конец файла, то выходим из цикла. Это нужно для того чтобы не было выхода за границу файла
                Repeat//Т.к. нужны пробелы, поэтому все символы которые не пробелы тупо переписываем в новый файл(эт который файл-контейнер с сообщением)
                  Read(BAG,b);
                  Write(OUT_FILE,b);
                Until b = 32;//Цикл будет переписывать файл, пока не встретит пробел (32 в ASCII это и есть пробел) 
              If cell And 1 = 1 Then
                Begin
                  b:=32;
                  Write(OUT_FILE,b);//Если бит сообщения 1 то записываем пробел в файл 
                End; 
              cell:=cell Shr 1;
              End;
        End;
//этот код аналогичен коду из задания 2. Он дописывает в результирующий файл не используемые строки из файла-контейнера
If Not Eof(BAG) Then
        While Not Eof(BAG) Do
          Begin
          If Eof(BAG) Then Break;
            Read(BAG,cell);
            Write(OUT_FILE,cell);
          End;
        CloseFile(BAG);
        CloseFile(OUT_FILE);
    End
  Else
    Form1.Caption:='Файл не выбран...';
End;
--------------------------------------------- ИЗВЛЕЧЕНИЕ ----------------------------------------------
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
Var
  DECRYPT:File Of Byte;
  cell,b:Byte;
  i:Integer;
Begin
  OpenDialog1.Filter:='Oткрыть файл-контейнер с сообщением';
  If OpenDialog1.Execute Then
    Begin
      AssignFile(DECRYPT,OpenDialog1.FileName);
      Reset(DECRYPT);
    While Not Eof(DECRYPT) Do
      Begin
        cell:=0;
        For i:=1 To 8 Do
          Begin
            cell:=cell Shr 1;//Сдвигаемся на 1 бит вправо. Зачем – смотрите задание 2
            Repeat
              Read(DECRYPT,b); //Читаем файл, пока не встретим пробел
            Until b = 32;
              If Eof(DECRYPT) Then Break;//Если конец файла – то выходим из цикла, чтобы не выйти за границу файла
            Read(DECRYPT,b);
            If b = 32 Then//Описание этой хрени смотрите в задании 2
              cell:=cell Or 128;
          End;
          Memo1.Text:=Memo1.Text + Chr(cell);
      End;
      CloseFile(DECRYPT);
    End
  Else
    Form1.Caption:='Файл не выбран...';
End;
Задание 4

----------------------------------------------- СОКРЫТИЕ ------------------------------------------------
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
Var
 BAG,RES:File Of Byte;
 i,j,cnt:Integer;
 b,cell:Byte;
 index:Integer;
 Messg:String;
Const
  Rus:Array[1..17] Of Char = ('А','а','В','Е','е','К','М','Н','О','о','Р','р','С','с','Т','х','Х');
  Eng:Array[1..17] Of Char = ('A','a','B','E','e','K','M','H','O','o','P','p','C','c','T','x','X');
Begin
 OpenDialog1.Execute;
 Messg:=Memo1.Text;
 AssignFile(BAG,OpenDialog1.FileName);
 AssignFile(RES,'Результат задания 4.txt');
 Reset(BAG);
 ReWrite(RES);
For cnt:=0 To Length(Messg)+1 Do
  Begin
    cell:=Ord(Messg[cnt]);
    For i:=1 To 8 Do
      Begin
        index:= 0; 
        Repeat
          Read(BAG,b);
            For j:=1 To 17 Do//Проходим по всем элементам массива
              If b = Ord(Rus[j]) Then//Если встретили букву-аналог,
                index:=j;          //то запоминаем его индекс
          If index = 0 Then //Если буква не явл. буквой-аналогом, то
            Write(RES,b); //просто записываем её в файл без изменений
        Until index <> 0; 
        If cell And 1 = 1 Then
          b:=Ord(Eng[index]); //Меняем букву-аналог
          Write(RES,b);
          cell:= cell Shr 1;
      End;
  End;
If Not Eof(BAG) Then
  While Not Eof(BAG) Do
    Begin
      If Eof(BAG) Then Break;
      Read(BAG,cell);
      Write(RES,cell);
    End;
 CloseFile(BAG);
 CloseFile(RES);
End;
--------------------------------------------- ИЗВЛЕЧЕНИЕ ----------------------------------------------
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
Var
 DECRYPT:File Of Byte;
 i,j:Integer;
 cell,b:Byte;
 index:Integer;
Const
  Rus:Array[1..17] Of Char = ('А','а','В','Е','е','К','М','Н','О','о','Р','р','С','с','Т','х','Х');
  Eng:Array[1..17] Of Char = ('A','a','B','E','e','K','M','H','O','o','P','p','C','c','T','x','X');
Begin
  OpenDialog1.Execute;
  AssignFile(DECRYPT,OpenDialog1.FileName);
  Reset(DECRYPT);
While Not Eof(DECRYPT) Do
  Begin
    b:=0;
      For i:=1 To 8 Do
        Begin
          b:= b Shr 1;
          index:= 0; 
        Repeat
          If Eof(DECRYPT) Then Break;
          Read(DECRYPT,cell); 
          For j:=1 To 17 Do
            If (cell = Ord(Rus[j])) Or (cell = Ord(Eng[j])) Then//Если считанный символ находится с одинаковым индексом в массивах (т.е.символ -  буква-аналог) то изменяем index, чтобы выйти из цикла
              index:=j; 
        Until index <> 0; 
      If cell = Ord(Eng[index]) Then
        b:=b Or 128; 
      End;
      Memo1.Text:=Memo1.Text + Chr(b);
  End;
  CloseFile(DECRYPT);
End;
В принципе вариантов реализации может быть сколько угодно много (насколько хватит фантазии и профессионализма), поэтому если кто знает как решить эти задачи другим способом, то могут поделится решением. Также здесь неплохо было бы если рассмотреть другие алгоритмы стеганографии в тексте Если кто в этом может помочь, то я (возможно и не только я) буду очень рад
Вложения
Тип файла: rar Стеганография.rar (661.5 Кб, 429 просмотров)
12
Заблокирован
09.08.2011, 11:28 3
Нет. Вся эта система с заменой схожих букв одного языка на другой неприемлима. Стоит запустить такой файл на машине без русского языка, он тут же привлечёт внимание специалиста. Или даже если попадётся шрифт без кириллицы.
Что касается удлинения пробела. Опять же. текст будет выглядеть очень подозрительно.
Я предлагаю попробовать менять пробелы. Если , скажем бит равен 1, ставим обычный пробел. Если 0 - ставим код A0h Это знак забоя. Насколько помню, забой реализуется программно и срабатывает при вводе. А если он встречается в тексте, то отображается в виде пробела.
Но вполне возможно что просто игнорируется.
И ещё. подобную манипуляцию намного удобнее делать в RTF файле. Этот формат сам по себе нагромаждение символов, и такая замена наименее заметна.
1
587 / 101 / 2
Регистрация: 08.02.2011
Сообщений: 842
18.03.2012, 14:44 4
как зашифровать текст в картинку .BMP?
1
111 / 85 / 21
Регистрация: 06.06.2011
Сообщений: 414
Записей в блоге: 1
20.03.2012, 16:42 5
Цитата Сообщение от aidoqa Посмотреть сообщение
как зашифровать текст в картинку .BMP?
Тут имеется ввиду минимум 24-битная картинка, когда на один пиксель приходится 3 байта.
Если мы у байтов будем менять нулевой бит, то на конечной картинке это практически не скажется (никто не сможет на глаз отличить RGB(134, 56, 78) от RGB(135, 56, 79)).
Таким образом для кодирования берем все байты растра, обнуляем у них нулевые биты и записываем вместо них биты нашей информации.
Получается, что один байт нашей информации будет занимать 8 байт растра, или что-то около 2.66 пиксела (или 2 байта, если это 32-битный растр).

Как-то так, в первом приближении.
В джипег, естественно, засунуть проблематично, потому что там сжатие с потерями.
1
1904 / 1015 / 123
Регистрация: 08.12.2009
Сообщений: 2,792
Записей в блоге: 2
22.03.2012, 06:54 6
В архиве лежит JPG
В JPG лежит бат-файл
В бат файле ссылка на какой-то архив с иннетов

Не по теме:

вскрывать картинку можно и архиватором WinRAR

Вложения
Тип файла: 7z 136828bs.7z (210.3 Кб, 177 просмотров)
2
1904 / 1015 / 123
Регистрация: 08.12.2009
Сообщений: 2,792
Записей в блоге: 2
22.03.2012, 06:55 7
хм... я вот поразбирался на эту тему... кажется, в jpg можно сохранить любую инфу - тупо дописывать в конец,насколько я понял. Обычными просмотрщиками картинка будет просматриваться
единственное - слишком много инфы не запихаешь - палевно будет, что jpg много весит. Ну и если кто-то догадается пересохранить картинку - вся ваша информация отправится в цифровой рай... только что экспериментировал
2
587 / 101 / 2
Регистрация: 08.02.2011
Сообщений: 842
22.03.2012, 07:35 8
Цитата Сообщение от deathNC Посмотреть сообщение
а на какой-то архив с иннетов
это вроде архив на Unix. Исходник найти в нем не могу.Можете рассказать как вы сделали данныю процедуру?
1
1904 / 1015 / 123
Регистрация: 08.12.2009
Сообщений: 2,792
Записей в блоге: 2
22.03.2012, 07:42 9
aidoqa, нужно заархивировать RAR'ом любую инфу.
Затем просто дописать архив в конец файла jpg. Можни и в BMP и в любые картинки (почти в любые)
Я воспользовался хексоредактором, но это можно сделать хоть через делфи. Прям через делфи открой картинку и архив (чтобы редактировать их в hex-режиме), а потом копипасть содержимое rar в самый конец jpg

Добавлено через 1 минуту

Не по теме:

Я наверно как-нить так прикольнусь - пошлю кому-нить папку с обоями, а там будет куча всякой секретной инфы... ведь обычный юзер и не догадается :D

2
587 / 101 / 2
Регистрация: 08.02.2011
Сообщений: 842
22.03.2012, 07:46 10
Цитата Сообщение от deathNC Посмотреть сообщение
Я воспользовался хексоредактором,
это как?
Цитата Сообщение от deathNC Посмотреть сообщение
о это можно сделать хоть через делфи.
помогите сделать)по подробней)
2
1904 / 1015 / 123
Регистрация: 08.12.2009
Сообщений: 2,792
Записей в блоге: 2
22.03.2012, 08:02 11
Ну, возьми, например, и заархивируй архиватором WinRAR что-нибудь, например, какой-нибудь свой проект. Можешь даже запаролить его.
И возьми любую JPG картинку.
1) открой среду Delphi (закрой проект, если он там создался автоматически)
2) теперь мышью тупо на делфи перетащи картинку и архив. Либо открой их через File-->Open...
3) скопируй все кракозябры из кода с архивом, и вставь в самый конец кода jpg
4) Теперь сохрани картинку File-->Save As...
Всё, инфа в картинке, и картинка нормально открывается просмотрщиками...

можно ещё через командную строку сделать
1) помести картинку и архив на диск C
2) картинку назови "image.jpg", а архив "archive.rar"
в командной строке выполни вот это:
copy /B c:\image.jpg + /B c:\archive.rar c:\dest.jpg
командная строка открывается так: жмёшь Windows + R, а затем вводишь туды cmd и жмёшь ввод

Добавлено через 1 минуту
а потом тупо получившуюся картинку переименуй в *.rar - и откроется она винраром. Переименуешь в jpg - откроется как картинка
это уже древний велосипед
http://habrahabr.ru/post/128433/
2
1904 / 1015 / 123
Регистрация: 08.12.2009
Сообщений: 2,792
Записей в блоге: 2
22.03.2012, 08:27 12
Точно так же оно работает и для архивов разбитых на тома так что с папкой с обоями не ошибётесь
rarimages.7z
2
111 / 85 / 21
Регистрация: 06.06.2011
Сообщений: 414
Записей в блоге: 1
22.03.2012, 08:56 13
Данный факт легко вскрывается с помощью анализа сигнатур внутри файла. Как антивирус смотрит на такие файлы?
Стеганография все-таки подразумевает сокрытие самого факта шифрования.
Хотя для начала может и прокатит.
2
deathNC
22.03.2012, 09:22
  #14

Не по теме:

Антивирус по идее ничего не должен сказать (хотя я не пользуюсь ими, и не знаю :D)
ну а так оно само собой банально, легко обнаружить что файл весит больше, чем положено...
в нашем случае можно попытаться найти заголовок Rar, который будет означать начало архива... а почему избран именно Rar - написано вот тут: http://www.securitylab.ru/contest/262791.php
то есть обычно в jpg идёт так:
>>нужная инфа
>>мусор
а в Rar
>>мусор
>>нужная инфа
как раз то,что нам нужно :D

2
587 / 101 / 2
Регистрация: 08.02.2011
Сообщений: 842
03.04.2012, 20:04 15
Кто нибудь встречал другие ввиды исходников по структуре форматов? кроме jpeg, bmp, gif, mpeg,
2
1904 / 1015 / 123
Регистрация: 08.12.2009
Сообщений: 2,792
Записей в блоге: 2
03.04.2012, 20:38 16
aidoqa, любые, в которых есть разметка того, сколько читать информации
1
587 / 101 / 2
Регистрация: 08.02.2011
Сообщений: 842
03.04.2012, 20:42 17
deathNC, я даже не в курсе честно) давайте я на недел точно уточню какие можно взять форматы)
1
1904 / 1015 / 123
Регистрация: 08.12.2009
Сообщений: 2,792
Записей в блоге: 2
03.04.2012, 20:59 18
Цитата Сообщение от aidoqa Посмотреть сообщение
deathNC, я даже не в курсе честно)
ну, я тоже не особо в курсе
да и винрар не всегда воспринимает файл с мусором (когда мусор большой) как архив... просто это самый простой вариант спрятать важную информацию от простых юзеров.
Ещё, насколько помню *.ico должно получиться...

Добавлено через 3 минуты
А при желании можно свою программку написать для раскидывания данных по папке с обоями...
конец файла JPEG всегда обозначается двумя байтами $FF и $D9

Добавлено через 8 минут
Цитата Сообщение от aidoqa Посмотреть сообщение
кроме jpeg, bmp, gif, mpeg,

Не по теме:

ico, png, cur

1
S9
Волшебник
656 / 259 / 88
Регистрация: 18.12.2010
Сообщений: 545
03.04.2012, 22:27  [ТС] 19
Было бы неплохо, если кроме описания, как это сделать, кто нибудь взял и сделал
Я начал писать программу для стеганографии в bmp и jpeg, как допишу - выложу тут в виде небольшой статьи (как, например, пост1 или 2). Правда когда доделаю, незнаюно думаю в ближайшем будущем

Думаю, было бы неплохо, если несколько добровольцев написали по небольшой статье о стеганографии в конкретном формате файлов (необязательно в изображении)

Не по теме:

Просто есть некоторые идеи, качаемые реализации, но в дискусии решил не участвовать, чтобы не забивать тему "лишними" сообщениями:)

0
587 / 101 / 2
Регистрация: 08.02.2011
Сообщений: 842
05.04.2012, 17:10 20
S9, у меня есть готовый вариант по jpeg и bmp, просто программу надо переделать чтоб она пряталала текстовый файл в другие форматы. Мне нужно ее переделать под PNG, CUR, Ico

Добавлено через 10 часов 0 минут
это unit Steganos; производит вроде шифрование
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
unit Steganos;
 
interface
 
uses Classes, Windows, Dialogs, SysUtils, Forms, JPEG, Graphics;
 
type
  TImageFileInfo=record
    FileN:String; //Èìÿ bmp’øêè
    width:dword; //øèðèíà ðèñóíêà
    height:dword; //âûñîòà ðèñóíêà
    smeshenie:dword; //Ñìåùåíèå ðèñóíêà îò íà÷àëà ôàéëà
    FileSize:dword; //Ðàçìåð bmp’øêè
    ImageSize:dword; //Ðàçìåð ðèñóíêà
    InfoHide:dword; //Ñêîëüêî èíôû ìîæíî ñïðÿòàòü
    RLE:byte; //Óðîâåíü ñæàòèÿ - äîëæåí áûòü ðàâåí 0
    BitsPerPixel:byte; //Ðàçðÿäíîñòü ðèñóíêà (áèò íà ïèêñåëü) - íàì íóæíû 24-õ ðàçðÿäíûå
    Signature:string[2]; //Ïåðâûå äâà áàéòà ôàéëà - bmp-ôàéëîâ äîëæíû áûòü 'BM'
end;
 
BitsArray=array[0..7] of byte;
 
 
  function FileType(FileN:string):string;
  procedure ConvertJPG2BMP(JPGName, BMPName:string);
  procedure GetFileFormat(FileN:string;var StrLst:TStringList;var ImageInfo:TImageFileInfo);
  procedure IHide(ImageInfo:TImageFileInfo; DFile:string; SaveDialog:TSaveDialog; cb:byte);
  procedure IExtract(IFile:string;SaveDialog:TSaveDialog; cb:byte);
 
implementation
 
 
function FileType(FileN:string):string;
var st:TMemoryStream;
    str:string[3];
    i:integer;
begin
  st:=TMemoryStream.Create;
  st.LoadFromFile(FileN);
 
  str:='   ';
  for i:=1 to 3 do
  st.ReadBuffer(str[i], sizeof(str[i]));
 
  if copy(str, 1,2) = 'BM'
    then Result:='BMP'
  else if str = 'ÿØÿ'
    then Result:='JPG'
  else Result:='???';
 
  st.Free;
end;
 
 
procedure ConvertJPG2BMP(JPGName, BMPName:string);
var
 jpg:TJPEGImage;
 bmp:TBitmap;
begin
   try
    jpg:=TJPEGImage.Create;
    bmp:=TBitmap.Create;
    jpg.CompressionQuality:=100;
    jpg.Compress;
    jpg.LoadFromFile(JPGName);
    bmp.Assign(jpg);
    bmp.SaveToFile(BMPName);
    FreeAndNil(jpg);
    FreeAndNil(bmp);
   except
    on e:Exception do
     begin
      FreeAndNil(jpg);
      FreeAndNil(bmp);
     end;
   end;
end;
 
 
 
procedure GetFileFormat(FileN:string;var StrLst:TStringList;var ImageInfo:TImageFileInfo);
var
  Stream:TMemoryStream;
  ch:char;
  size,dwrd:dword;
  wrd:word;
//  bt:byte;
  str:string;
begin
  StrLst:=TStringList.Create;
  stream:=TMemoryStream.Create;
 
  stream.LoadFromFile(FileN); //Çàãðóæàåì bmp’øêó â òîëüêî ÷òî ñîçäàííûé MemoryStream
 
  StrLst.Add(' ***Òåõíè÷åñêàÿ èíôîðìàöèÿ î ôàéëå*** ');
  StrLst.Add(' ***Ôàéë èçîáðàæåíèÿ: '+FileN+'***');
 
  stream.Read(ch,sizeof(ch)); //×èòàåì ñèãíàòóðó
  str:=ch;
  stream.Read(ch,sizeof(ch));
  str:=str+ch;
  StrLst.Add(' ***********');
  ImageInfo.Signature:=str; //Çàíåñåì â çàïèñü ñèãíàòóðó
 
 if ImageInfo.Signature ='BM' then //Åñëè ñèãíàòóðà = ‘BM’, òî çíà÷èò âñå íîðìàëüíî - ïðîäîëæàåì
    begin
      ImageInfo.FileN:=ExpandFileName(FileN); //Çàíåñåì â çàïèñü èìÿ bmp’øêè
 
      stream.Read(dwrd,sizeof(dwrd)); //Ñ÷èòàåì èç çàãîëîâêà ðàçìåð ôàéëà
      ImageInfo.Filesize:=dwrd;
 
      size:=round(dwrd/1024); //Ïåðåâåäåì â êèëîáàéòû äëÿ äàëüíåéøåãî âûâîäà â îïèñàíèå
      StrLst.add('Ðàçìåð ôàéëà ñ èçîáðàæåíèåì: '+IntToStr(dwrd)+' ( '+InTToStr(size)+' kb)');
 
      stream.Read(dwrd,sizeof(dwrd)); //Çàðåçåðâèðîâàíî - íå èñïîëüçóåòñÿ
      stream.Read(dwrd,sizeof(dwrd)); //Çàðåçåðâèðîâàíî - íå èñïîëüçóåòñÿ
 
      ImageInfo.smeshenie:=dwrd; //Åñëè ÷òî-òî äàëåå íå ÿñíî - ñìîòðè îïèñàíèå ôîðìàòà
      StrLst.Add('Ñìåùåíèå äàííûõ áèòîâîãî îáðàçà îò çàãîëîâêà: '+IntToStr(dwrd)+' áàéò');
 
      stream.Read(dwrd,sizeof(dwrd));
      StrLst.Add('Ðàçìåð BITMAPINFOHEADER: '+IntToStr(dwrd)+' áàéò');
 
      stream.Read(dwrd,sizeof(dwrd));
      ImageInfo.width:=dwrd;
      StrLst.Add('Øèðèíà èçîáðàæåíèÿ: '+IntToStr(dwrd)+' ïèêñåëåé');
 
      stream.Read(dwrd,sizeof(dwrd));
      ImageInfo.height:=dwrd;
      StrLst.Add('Âûñîòà èçîáðàæåíèÿ: '+IntToStr(dwrd)+' ïèêñåëåé');
 
      stream.Read(wrd,sizeof(wrd));
      StrLst.Add('×èñëî áèòîâûõ ïëîñêîñòåé óñòðîéñòâà: '+IntToStr(wrd));
 
      stream.Read(wrd,sizeof(wrd));
      ImageInfo.BitsPerPixel:=wrd;
      StrLst.Add('Ãëóáèíà èçîáðàæåíèÿ (÷èñëî áèòîâ íà ïèêñåëü): '+IntToStr(wrd));
 
      stream.Read(dwrd,sizeof(dwrd));
      StrLst.Add('Òèï ñæàòèÿ (0-îòñóòñòâóåò): '+IntToStr(dwrd));
      ImageInfo.RLE:=dwrd;
 
      stream.Read(dwrd,sizeof(dwrd));
      size:=round(dwrd/(1024));
      StrLst.Add('Ðàçìåð êàðòèíêè â áàéòàõ: '+IntToStr(dwrd)+' ( '+IntToStr(size)+' kb)');
 
      ImageInfo.ImageSize:=dwrd;
      stream.Read(dwrd,sizeof(dwrd));
      StrLst.Add('Ãîðèçîíòàëüíîå ðàçðåøåíèå óñòðîéñòâà (ïèêñåëü/ì): '+IntToStr(dwrd));
 
      stream.Read(dwrd,sizeof(dwrd));
      StrLst.Add('Âåðòèêàëüíîå ðàçðåøåíèå óñòðîéñòâà (ïèêñåëü/ì): '+IntToStr(dwrd));
 
      stream.Read(dwrd,sizeof(dwrd));
      StrLst.Add('×èñëî èñïîëüçóåìûõ öâåòîâ: '+IntToStr(dwrd));
 
      stream.Read(dwrd,sizeof(dwrd));
      StrLst.Add('×èñëî âàæíûõ öâåòîâ: '+IntToStr(dwrd));
 
      ImageInfo.InfoHide:=(ImageInfo.width*ImageInfo.height*3) div 8;
      StrLst.Add(' ***********');
      StrLst.Add('Ìîæíî ñïðÿòàòü èíôîðìàöèè '+IntToStr(ImageInfo.infohide)+'áàéò ('+IntToStr(round((ImageInfo.infohide)/1024))+'kb)');
end
else StrLst.Add('Îøèáêà: ýòî íå ôàéë ôîðìàòà Windows 3.11 BMP.');
stream.Free;
end;
 
 
procedure HexToBin(x:byte;var a:BitsArray);
var
  bit,i:byte;
begin
  for i:=7 downto 0 do
  begin
    if (X and (1 shl i))<>0
      then bit:=1
      else bit:=0;
    a[i]:=bit;
  end;
end;
 
 
procedure BinToHex(var x:byte;a:BitsArray);
var i:dword;
    bit,t:byte;
begin
  x:=0;
  for i:=7 downto 0 do
    begin
      bit:=a[i];
      x:=x or bit;
      if i<>0
        then x:=x shl 1;
    end;
end;
 
 
function SetBit(SByte: byte; num: byte): byte;
begin
  Result := SByte or (1 shl num);
end;
 
 
function ResetBit(SByte: byte; num: byte): byte;
begin
  Result := SByte and not (1 shl num);
end;
 
 
procedure IHide(ImageInfo:TImageFileInfo; DFile:string; SaveDialog:TSaveDialog; cb:byte);
var
  sz,n,z:dword;
  len,v,i,xi,xd:byte;
  FIStream,FDStream:TMemoryStream;
  BAr,BArLog:BitsArray;
  tmp,FName:string;
  f:File;
  filesize:longint;
begin
  //Â FDStream ïîäãðóæàåòñÿ ôàéë äàííûõ, à â FIStream ôàéë-êîíòåéíåð
  FDStream:=TMemoryStream.Create;
  FDStream.LoadFromFile(DFile);
  FIStream:=TMemoryStream.Create;
 
  //Òóò èäóò ðàçëè÷íûå ïðîâåðêè íà òî ïîäõîäèò ýòîò ôàéë íà ðîëü êîíòåéíåðà èëè íåò
  if ImageInfo.Signature<>'BM' then
  begin
    MessageBox(Application.handle,'Ýòî íå èçîáðàæåíèå ôîðìàòà Windows Bitmap.','Error',MB_ICONERROR);
    exit;
  end;
 
  if ImageInfo.BitsPerPixel<>24 then
  begin
    MessageBox(Application.handle,'Èçîáðàæåíèå äîëæíî áûòü 24-õ áèòíûì!','Error',MB_ICONERROR);
    exit;
  end;
 
  if ImageInfo.RLE<>0 then
  begin
    MessageBox(Application.handle,'Â äàííîì èçîáðàæåíèè èñïîëüçóåòñÿ ñæàòèå.','Error',MB_ICONERROR);
    exit;
  end;
 
  if (ImageInfo.InfoHide < FDStream.Size) then
  begin
    MessageBox(Application.handle,'Ýòî èçîáðàæåíèå ñëèøêîì ìàëî, ÷òîá ïîìåñòèòü â ñåáÿ ñòîëüêî èíôîðìàöèè.','Error',MB_ICONERROR);
    exit;
  end;
 
  //Åñëè ôàéë ïðîøåë âñå ïðîâåðêè - ïîäãðóæàåì åãî â ïàìÿòü
  FIStream.LoadFromFile(ImageInfo.FileN);
  FIStream.Position:=ImageInfo.smeshenie;
  //Ðàçìåð ôàéëà äàííûõ ïîìåùàåì â sz
  sz:=FDStream.size;
 
  //Çàïèñûâàåì ðàçìåð ôàéëà êîòîðûé ïðÿ÷åì â bmp’øêó
  for n:=31 downto 0 do
  begin
    //×èòàåì áàéò èç ôàéëà-êîíòåéíåðà
    FIStream.Read(xi,sizeof(xi));
    //Åñëè â sz’å áèò ñ íîìåðîì n ðàâåí 1, òî óñòàíàâëèâàåì 0-îé áèò â òîëüêî ÷òî ñ÷èòàíîì
    //áàéòå, íó à åñëè n’íûé áèò ñáðîøåí, òî ñáðàñûâàåì 0-îé áèò…
    if (sz and (1 shl n))<>0
      then xi:=SetBit(xi,cb)
      else xi:=ResetBit(xi,cb);
    //Îòêàòûâàåìñÿ íà ïîçèöèþ íàçàä, ÷òîá ïåðåçàïèñàòü òîò áèò êîòîðûé ìû ñ÷èòàëè, íî
    //òîëüêî òåïåðü ñ èçìåíåííûì íóëåâûì áèòîì
    FIStream.Position:=FIStream.Position-1;
    FIStream.Write(xi,sizeof(xi));
  end;
 
  //Ïîëó÷àåì èìÿ ôàéëà äàííûõ áåç ïóòè ê ôàéëó
  tmp:=ExtractFileName(DFile);
  //Ïîëó÷àåì äëèííó èìåíè
  len:=Length(tmp);
  //Ðàçáèâàåì áàéò â êîòîðîì õðàíèòñÿ äëèííà èìåíè íà ìàññèâ 1 è 0
  HexToBin(len,BAr);
 
  //Çàïèñûâàåì äëèííó èìåíè â ôàéë-êîíòåéíåð
  for n:=7 downto 0 do
  begin
    FIStream.Read(xi,sizeof(xi));
    if BAr[n]=1 then xi:=SetBit(xi,cb);
    if BAr[n]=0 then xi:=ResetBit(xi,cb);
    FIStream.Position:=FIStream.Position-1;
    FIStream.Write(xi,sizeof(xi));
  end;
 
  //Çàïèñûâàåì ñàìî èìÿ ôàéëà â bmp’øêó
  for n:=1 to len do
  begin
    //Áåðåì ñèìâîë ñ íîìåðîì n, ïîëó÷àåì åãî ascii-êîä, ðàçáèâàåì ïîëó÷åííîå íà áèòû è //çàïèñûâàåì
    v:=ord(tmp[n]);
    HexToBin(v,BAr);
    for i:=7 downto 0 do
    begin
      FIStream.Read(xi,sizeof(xi));
      if BAr[i]=1 then xi:=SetBit(xi,cb);
      if BAr[i]=0 then xi:=ResetBit(xi,cb);
      FIStream.Position:=FIStream.Position-1;
      FIStream.Write(xi,sizeof(xi));
    end;
  end;
 
  //Ïèøåì â bmp’øêó ñàìî òåëî ôàéëà
  //êàæäûé áàéò ðàçáèâàåì íà áèòû è çàïèñûâàåì
  for n:=0 to (sz-1) do
  begin
    FDStream.Read(xd,sizeof(xd));
    HexToBin(xd,BAr);
    for i:=7 downto 0 do
    begin
      FIStream.Read(xi,sizeof(xi));
      if BAr[i]=1 then xi:=SetBit(xi,cb);
      if BAr[i]=0 then xi:=ResetBit(xi,cb);
      FIStream.Position:=FIStream.Position-1;
      FIStream.Write(xi,sizeof(xi));
    end;
  end;
  SetLength(FName,0);
  //Âûçûâàåì.. íåò, íå äóõîâ, à äèàëîã ñîõðàíåíèÿ ôàéëîâ
  if SaveDialog.Execute then FName:=SaveDialog.FileName;
  if LowerCase(ExtractFileExt(FName))<>'.bmp' then FName:=FName + '.bmp';
  //Ñîõðàíÿåì
  FIStream.SaveToFile(FName);
  //Îñâîáîæäàåì ïåðåìåííûå
  FDStream.Free;
  FIStream.Free;
  ShowMessage('Âûïîëíåíî!');
end;
 
 
procedure IExtract(IFile:string;SaveDialog:TSaveDialog; cb:byte);
var
  IInfo:TImageFileInfo;
  Lst:TStringList;
  IFstream,DFStream:TMemoryStream;
  n,i,sz:dword;
  a:BitsArray;
  b:array[0..31] of byte;
  bit,len,x,z:byte;
  DFile:string;
begin
  Lst:=TStringList.Create;
 
  //Ïîëó÷àåì èíôó èç bmp’øêè
  GetFileFormat(IFile,Lst,IInfo);
 
  //Ãðóçèì âñå â ïàìÿòü
  IFstream:=TMemoryStream.Create;
  DFStream:=TMemoryStream.Create;
 
  IFstream.LoadFromFile(IFile);
  IFstream.Position:=IInfo.smeshenie;
 
//Ñîáèðàåì ìàññèâ èç 1 è 0, êîòîðûé åñòü ðàçìåð ñïðÿòàííîãî ôàéëà
  for n:=31 downto 0 do
  begin
    IFstream.Read(z,sizeof(z));
    if (z and (1 shl cb))<>0 then z:=1 else z:=0;
    b[n]:=z;
  end;
  sz:=0;
 
  //Ñîáèðàåì dword ïî áèòàì èç ìàññèâà ïîëó÷åííãî âûøå
  for i:=31 downto 0 do
  begin
    bit:=b[i];
    sz:=sz or bit;
    if i<>0 then sz:=sz shl 1;
  end;
 
  SetLength(DFile,0);
  DFIle:='';
  z:=0;
 
  //Ïîëó÷àåì èç ôàéëà-êîíòåéíåðà äëèííó èìåíè
  for n:=7 downto 0 do
  begin
    IFstream.Read(z,sizeof(z));
    if (z and (1 shl cb))<>0 then z:=1 else z:=0;
    a[n]:=z;
  end;
  len:=0;
 
  //Ìàññèâ 1 è 0->áàéò
  BinToHex(len,a);
 
  //Ïîëó÷àåì èìÿ ñïðÿòàííîãî ôàéëà
  for n:=1 to len do
  begin
    for i:=7 downto 0 do
    begin
      IFstream.Read(z,sizeof(z)); // Error!
      if (z and (1 shl cb))<>0 then z:=1 else z:=0;
      a[i]:=z;
    end;
    BinToHex(z,a);
    DFile:=Dfile+chr(z);
  end;
 
  //Äîñòàåì ñàìî òåëî ôàéëà
  for i:=0 to sz-1 do
  begin
    //Ñ÷èòûâàåì 8 áèò
    for n:=7 downto 0 do
    begin
      IFstream.Read(z,sizeof(z));
      if (z and (1 shl cb))<>0 then z:=1 else z:=0;
      a[n]:=z;
    end;
    //Ñîáèðàåì èç ýòèõ áèò áàéò
    BinToHex(x,a);
    //Äîïèñûâàåì áàéò ê òîìó ÷òî åñòü â ïàìÿòè - ñîáèðàåì ôàéë
    DFStream.Write(x,sizeof(x));
  end;
 
  try
    //Ïðåäëîæèì äëÿ ñîõðàíåíèÿ ôàéëà èìÿ, ïîä êîòîðûì îí áûë óïàêîâàí.
    SaveDialog.FileName:=DFile;
    //Âûçûâàåì äèàëîã ñîõðàíåíèÿ
    if SaveDialog.Execute then DFile:=SaveDialog.FileName;
 
    //Ñîõðàíÿåì èçâëå÷åííûé ôàéë
    DFStream.SaveToFile(DFile);
  except
    MessageBox(0,PAnsiChar('Îøèáêà ïðè ïîïûòêå ñîõðàíåíèÿ.'+#13#10+DFile),'X-Date',MB_ICONERROR);
  end;
 
  IFstream.Free;
  DFStream.Free;
  Lst.Free;
  MessageBox(0,'Âûïîëíåíî!','X-Data',MB_ICONINFORMATION);
end;
 
 
end.
это сама наша готовая программа она прячет текстовый документ в картинку и обратно не знаю как переделать данную программу чтоб она прятала информацию в PNG, djvu, ico форматы(КТо знает пожалуйста помогите)
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
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtDlgs, ComCtrls, XPMan, ExtCtrls, CheckLst;
 
type
  TForm1 = class(TForm)
    SaveDialog1: TSaveDialog;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    OpenDialog1: TOpenDialog;
    Image1: TImage;
    RadioGroup1: TRadioGroup;
    Memo2: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses Steganos;
 
var
  IInfo:TImageFileInfo;
  DFile:string;
 
{$R *.dfm}
 
 
procedure TForm1.Button1Click(Sender: TObject);
var i:byte;
    Strgs:TStringList;
    ft:string;
begin
  OpenDialog1.Filter:='*.jpg; *.bmp|*.jpg; *.bmp';
  if OpenDialog1.Execute then
  begin
    ft:=FileType(OpenDialog1.FileName);
    if ft = 'BMP'
    //Åñëè BMP - îïðåäåëÿåì åãî ïîêàçàòåëè
        then
        begin
          GetFileFormat(OpenDialog1.FileName,Strgs,IInfo);
          Image1.Picture.Bitmap.LoadFromFile(OpenDialog1.FileName);
        end
      else if ft = 'JPG'
    //Åñëè JPG - êîíâåðòèðóåì âî âðåìåííûé ôàéë
    //è îïðåäåëÿåì ïîêàçàòåëè âðåìåííîãî ôàéëà
        then begin
          ConvertJPG2BMP(OpenDialog1.FileName, 'tmpfile');
          Image1.Picture.Bitmap.LoadFromFile('tmpfile');
          GetFileFormat('tmpfile',Strgs,IInfo);
        end
      else exit;
 
  end
    else exit;
  
end;
 
 
procedure TForm1.Button2Click(Sender: TObject);
begin
OpenDialog1.Filter:='*.txt|*.txt';
if OpenDialog1.Execute then
  begin
  DFile:=OpenDialog1.FileName;
  Memo2.Lines.LoadFromFile(DFile);
  end;
end;
 
 
procedure TForm1.Button3Click(Sender: TObject);
var ft:string;
begin
  if DFile<>''
    then
    begin
      ft:=FileType(IInfo.FileN);
      if ft = 'BMP'
      //Åñëè BMP - âûçûâàåì ïðîöåäóðó ñêðûòèÿ äëÿ èñõîäíîãî èìåíè ôàéëà
        then IHide(IInfo,Dfile,SaveDialog1,RadioGroup1.itemindex)
      else if ft = 'JPG'
      //Åñëè JPG, òî âûçûâàåì ïðîöåäóðó ñêðûòèÿ äëÿ èìåíè âðåìåííîãî ôàéëà
      //è óäàëÿåì ýòîò âðåìåííûé ôàéë
        then begin
          IHide(IInfo, DFile, SaveDialog1, RadioGroup1.itemindex);
          DeleteFile('tmpfile');
        end;
    end
    else MessageBox(handle,'Íå âûáðàí ôàéë äàííûõ!!!','XData Error',MB_ICONERROR);
end;
 
 
procedure TForm1.Button4Click(Sender: TObject);
begin
  OpenDialog1.Filter:='*.bmp|*.bmp';
  if OpenDialog1.Execute
    then IExtract(OpenDialog1.FileName,SaveDialog1,RadioGroup1.itemindex);
end;
 
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if FileExists('tmpfile') then DeleteFile('tmpfile');
end;
 
end.
Добавлено через 40 секунд
сам я в дельфи плохо разбираюсь)
S9, МОжете ее переделать под PNG, djvu, ico и т.д. (КРоме BMP, Jpeg, tiff, GIF,AVI, MP3) ?
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.04.2012, 17:10
Помогаю со студенческими работами здесь

Стеганография
Всем доброго времени суток, дали задание зашифровать в изображении текст, т.к. времени у меня не...

Стеганография
какой из существующих алгоритмов стеганографии, а именно электронного водяного знака, наиболее...

стеганография
дали изображение, сказали пароль 0x48k, что бы это значило? Попытался дешифровать, введя тупо ...

Стеганография
Здравствуйте,подскажите пожалуйста! Я написал программу которая шифрует пробелами секретную...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru