Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Свежие комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 12 августа 2009 в 19:47.
Категории: Без категории, Основы Delphi.


Прежде, чем начнется техническая часть статьи, предлагаю Вам немного развлечься и поиграть в старую игру "Найди N-цать отличий". Вот две картинки.

Первая

Crypto_1

Вторая

001

Задание: найдите 10 различий в этих картинках :)< ' ' >

Собственно, даже если бы я дал Вам сравнить 2 картинки по-проще, то все-равно невооруженным глазом определить различия было бы практически невозможно.  А различаются картинки тем, что в первой записан текст, который гласит: "Привет от webdelphi.ru". Причем записан этот текст кусками по всей картинке.

Спрашивается: а нафига мне это надо?

Я не дизайнер и не художник, так что картинки мне защищать авторским правом явно не светит. Просто решил немного разобраться для себя с вопросами по работе с нетипизированными файлами. Вот и получилась небольшая программка, которая пишет в jpg-файл произвольные данные таким образом, чтобы минимально видоизменять первоначальное изображение. Где эту программу сможете использовать Вы я не имею понятия, но буду очень признателен, если Вы поделитесь со мной способами её применения.

А теперь, собственно, разберемся как эта программа действует. Во-первых JPEG как и любой другой формат файлов не является беспорядочным набором байт, а имеет чёткую спецификацию. В соответствие с которой, файл имеет свой заголовок и, в зависимости от файла один или несколько JPG-потоков, причем в файле может присутствовать: 1 поток (сама картинка) 2 потока (картинка и миниатюра), в случае 3-х потоков уже следует задуматься над тем, чтобы "почистить" картинку, т.к. обычно третьим потоком идет бесполезная инфа, записаная фотошопом и пр.

Так вот, если не нарушать заголовка, то в картинку в принципе, можно записать сколь угодно дополнительных данных. Например, моя программа действует следующим образом:

  1. Открывается файл с картинкой и из него копируется заголовок в новый файл
  2. Следом за заголовком вписывается ключ для расшифровки вписываемого текста
  3. Далее, в зависимости от потребностей, в файл с определенными промежутками вписываются части текста.
  4. Новый файл сохраняется с новым именем.

Теперь более детально, а точнее на языке Delphi. Во-первых, ключ представлен следующим образом:

type
TCryptoKey = record
Step   : byte;                  //шаг записи строки
length : word;               //длина части строки для записи
TextLength: integer; //общая длина строки
TextParts: byte;          //количество частей текста
end;

Зная ключ, можно без проблем восстановить все части текста и склеить их в первоначальный вид.

Сама процедура записи текста в картинку реализована следующим образом:

procedure PictCrypt(SourceFile, TargetFile: TFileName; CryptoKey:TCryptoKey; Text:String);
var FS, FT: File;
i,j,part:integer;
buf2: byte;
doWT: boolean; //флаг разрешения записи текста
ch:string[1];
begin
//получаем частитекста для шифровки
TextParts:=GetTextParts(Text, CryptoKey);
doWT:=false;
AssignFile(FS,SourceFile);
AssignFile(FT, TargetFile);
Reset(FS,1);
Rewrite(FT,1);
for I := 0 to FileSize(FS)-1 do
begin
if i=jpg_header+1 then
begin
//записываем в файл ключик
BlockWrite(FT, CryptoKey,Sizeof(CryptoKey));
doWT:=true;
part:=0; //элемент массива строк с которого начать писать
end;
if (doWT)and ((FilePos(FT) mod CryptoKey.Step)=0)and(part<=Length(TextParts)-1)  then
begin
for j:=1 to Length(TextParts[part]) do
begin
ch:=(copy(TextParts[part],1,1));
delete(TextParts[part],1,1);
BlockWrite(FT, ch ,sizeof(Ch));
end;
part:=part+1;
end;
BlockRead(FS, buf2, Sizeof(buf2));
BlockWrite(FT, buf2,Sizeof(buf2));
end;
CloseFile(FT);
CloseFile(FS);
end;

После того, как текст записан в картинку, его можно прочитать обратной функцией:

function PictDeCrypt(SourceFile: TFileName):string;
var i,j,k:integer;
buf: TCryptoKey;
FS: File;
pt: string[1];
begin
AssignFile(FS,SourceFile);
reset(FS,1);
for I := 0 to FileSize(FS)-1 do
begin
Seek(FS,jpg_header+1); //смещаемся на позицию начала ключа
BlockRead(FS, buf,Sizeof(buf));
CryptoKey:=buf;
//восстанавливаем длины подстрок, записаных в файле
LengthTextParts:=GetLengths(CryptoKey);
end;
for I:=FilePos(FS) to FileSize(FS)-1 do
begin
Seek(FS, i);
if ((i mod CryptoKey.Step)=0) then
begin
if i>=jpg_header+sizeof(buf)+1 then
begin
for k:=0 to Length(LengthTextParts)-1 do
begin
for j:=1 to LengthTextParts[k] do
begin
BlockRead(FS, pt ,Sizeof(pt));
Result:=Result+pt;
end;
Seek(FS,FilePos(FS)+CryptoKey.Step-sizeof(pt));
end;
break;
end;
end;
end;
CloseFile(FS);
end;

При этом, вначале расшифровки по известному ключу восстанавливаются длины кусков текста, записаных в картинке. Восcтановление длин оcуществляется в функции:

function GetLengths(CryptoKey: TCryptoKey):TLengthTextParts;
var i:integer;
begin
//восстанавливаем длины частей текста записаных в картинку
SetLength(Result, CryptoKey.TextParts);
for I:=1  to CryptoKey.TextParts-1 do
Result[i-1]:=CryptoKey.length;
{в последнюю часть дописываем остаток}
Result[Length(Result)-1]:=CryptoKey.length+(CryptoKey.TextLength-CryptoKey.length*CryptoKey.TextParts);
end;

Сама программа выглядит следующим образом:

screenprog

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

В итоге, после записи текста программа проверит своб работу и выведет в закладке "Техническая часть" проверяемые данные:

Если результат проверки Вас устраивает (текст читается без потерь) значит все замечательно, иначе процедуру записи следует повторить, изменив данные, например количество частей текста или размер самой строки. По предварительным данным, в картинку можно записывать до 1500 символов текста, но при этом на картинке появляется "рябь".

Так как сейчас я предоставляю Вам только наброски программы или, выражаясь более официально, бетта-версию :), то надеюсь на Ваше участие в развитии программы, указание ошибок, недочетов и пр. Кстати, я не первый, кто додумался до такого. Помню где-то год назад попадалась мне на глаза статья с подобным алгоритмом шифрования текста, но хоть убейте не могу её отыскать в Интернете, видимо администратор этого сайта не в курсе, что такое раскрутка веб сайта. Буду благодарен, если поделитесь ссылочкой на эту статью.

Кстати, если кто-то заинтересуется самим алгоритмом, то в принципе можно организовать запись любых данных, например массивов чисел и пр.

Файл для загрузки: CryptoPict.zip

Мой блог находят по следующим фразам

Мой блог находят по следующим фразам

Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (11)

WP_Cloudy
  • TEMA пишет:

    Помню где-то год назад попадалась мне на глаза статья с подобным алгоритмом шифрования текста, но хоть убейте не могу её отыскать в Интернете.
    Есть md5,  думаю ты и так об этом знаешь)
    Кстати говоря, есть программы, которые позволяют внести (записать) внутрь картинки мультемедиа файл (например музыку).

  • admin пишет:

    Знаю, что есть, но самому-то написать интереснее :)

  • Макс пишет:

    Сори. Но как сохранить зашифрованную картинку? У меня не получается.

  • Vlad пишет:

    В статье процедура procedure PictCrypt(SourceFile, TargetFile: TFileName; CryptoKey:TCryptoKey; Text:String);
    как раз и записывает в TargetFille зашифрованную картинку.

  • Сергей пишет:

    Этот код можно использовать в виде зашиты логотипов или рекламы. Типо есть прога в ней используется файл картинки с логотипом фирмы, в файле зашифрован код. А пользователь не может взять и заменить картинку своей со своим логотипом так как в ней нет кода, и прога отказывается запускатся.  :)

  • Vlad пишет:

    Логично :)

  • Алексей пишет:

    народ, берёте jpeg файл, добавляете в его конец архив (склеиваете файлы) и всё….переименовав jpg в zip — получаете архив, переименовав zip обратно в jpg — картинку…

  • саня пишет:

    такой вопрос а если наобород принимать зашифрованную картинку, как текст читать??????

  • Vlad пишет:

    Видимо надо выполнить операцию полностью противоположную операции шифрования.

  • Сергей пишет:

    А можно исходный код перекинуть(dpr+pas+dfm)?
     

  • TEKTON пишет:

    А если картинку редактировали, после того как в неё записан текст,  скажем в фотошопе ???
    Как это отобразится на тексте ?
     
     

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник