Модераторы: Snowy, Alexeis, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Стеганография 
:(
    Опции темы
HackMan
Дата 16.7.2005, 02:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Юзверь-программист
**


Профиль
Группа: Участник
Сообщений: 391
Регистрация: 18.6.2005
Где: .ua

Репутация: нет
Всего: 9



Меня очень интересует стеганография - скрытие одной информации в другой. Особенно интересует скрытие информации в картинках.

Скажите, где можно об этом подробно почитать? Желатьльно, чтобы там были программные реализации или алгоритмы.

Заранее благодарен smile


--------------------

Завтра - это самый загруженный день недели smile

user posted image

user posted image
PM MAIL ICQ   Вверх
Illusion Dolphin
Дата 16.7.2005, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 13
Всего: 63



Будешь должен ;) Я сегодня добрый smile
Код модуля, делает
Цитата
скрытие информации в картинках.

Алгоритм заключается в "небольшой" поправке BMP файла (хотя по сути можно любой растровый файл корябить), так что некоторая последовательность байтов делилась на 255 с остатком, равным нужной инфе... а если не понял, что я сказал, то читай сырцы:
Код

unit SaveInfoToImage;

{*******************************************************}
{                                                       }
{       Run-time Library for Borland Delphi 7           }
{       Saving info to bitmap image                     }
{                                                       }
{       Copyright (c)  2001-2005 by Veresov Dmitry      }
{                                                       }
{     *****                                             }
{     **   **                                           }
{     **    **       ************                       }
{     **    **     **     **     **                     }
{     **    **     **     **     **                     }
{     **   **      **     **     **                     }
{     *****        ***    ***    ****                   }
{                                                       }
{*******************************************************}

interface

uses dm, Math, Classes, SysUtils, Windows, Graphics;

type
  TRGB=record
  b,g,r : byte;
  end;
type
 TArByte = array of byte;
Type
    ARGB=array [0..1] of TRGB;
    PARGB=^ARGB;
    PRGB = ^TRGB;

// BeginImage преобразовывается в Tbitmap с учётом информации Info с ячейкой размером Cell
Function SaveInfoToBmpFile(BeginImage : TGraphic; Info : TArByte; Cell : Integer) : Tbitmap;
// достаём информацию из Bitmap
Function LoadInfoFromBitmap(Bitmap : TBitmap) : TArByte;
// достаём строку из Bitmap
Function LoadStringFromInfo(Info : TArByte) : String;
// достаём информацию из строки
Function LoadInfoFromString(Str : String) : TArByte;
// сохраняет имя файла в информацию
Function SaveFileToInfo(FileName : String) : TArByte;
// достаём информацию имя файла
Function GetFileNameFromInfo(Info : TArByte) : String;
// максимально возможное количество информации, которое можо записать в Graphic с ячейкой размером Cell
Function MaxSizeInfoInGraphic(Graphic : TGraphic; Cell : Integer) : Integer;
// сохраняет информацию в файл
Procedure SaveInfoToFile(Info : TArByte; FileName : String);
// выдаёт размер Cell, наиболее оптимальный если сохранять в Graphic информацию о файле FileName
function GetMaxPixelsInSquare(FileName : String; Graphic : TGraphic) : integer;
function GetFileName(Filename : string):string;
function GetFileSizeByName(FileName: String): Integer;

implementation

function GetFileName(filename:string):string;
var
  i, n : integer;
begin
 Result:='';
 If filename='' then exit;
 n:=0;
 for i:=length(filename)-1 downto 1 do
 If filename[i]='\' then
 begin
  n:=i;
  break;
 end;
 delete(filename,1,n);
 If filename<>'' then
 If filename[Length(filename)]='\' then
 Delete(filename,Length(filename),1);
 result:=filename;
end;

function GetFileSizeByName(FileName: String): Integer;
var
  FindData: TWin32FindData;
  hFind: THandle;
begin
  Result := -1;
  hFind := FindFirstFile(PChar(FileName), FindData);
  if hFind <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(hFind);
    if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
      Result := FindData.nFileSizeLow;
  end;
end;

procedure SetPixel(P : PRGB; var C : Integer);

procedure SetByte(var B : Byte);
begin
 if c>0 then
 begin
  if b<$ff then
  begin
   b:=b+1;
   dec(c);
  end;
 end;
 if c<0 then
 begin
  if b>$0 then
  begin
   b:=b-1;
   inc(c);
  end;
 end;
end;

begin
 SetByte(p.r);
 SetByte(p.g);
 SetByte(p.b);
end;

Function SaveInfoToBmpFile(BeginImage : TGraphic; Info : TArByte; Cell : Integer) : Tbitmap;
var
  XP : array of PARGB;
  s, i, j, k, l, c ,n, Size : integer;
  bsize : array[1..5] of byte;
begin
 Result:=nil;
 if Cell>23 then Exit;
 if Cell<2 then Exit;
 Result:=TBitmap.create;
 if BeginImage is TIcon then
 begin
  Result.Width:=BeginImage.Width;
  Result.Height:=BeginImage.Height;
  Result.Canvas.Draw(0,0,BeginImage);
 end else
 Result.Assign(BeginImage);
 Result.PixelFormat:=pf24bit;
 SetLength(XP,Result.Height);
 for i:=0 to Result.Height-1 do
 XP[i]:=Result.ScanLine[i];
 Size:=Length(Info);
 bsize[1]:=Cell;
 bsize[2]:=Size mod 256;
 Size:=Size div 256;
 bsize[3]:=Size mod 256;
 Size:=Size div 256;
 bsize[4]:=Size mod 256;
 Size:=Size div 256;
 bsize[5]:=Size mod 256;
 Size:=Length(Info);
 n:=0;
 s:=XP[0,0].r+XP[0,0].g+XP[0,0].b;
 c:=Cell-s mod 24;
 if s+c>254*3 then
 c:=c-24;
 if s+c<0 then
 c:=c+24;
 Repeat
  SetPixel(@XP[0,0],c);
 Until c=0;
 for i:=0 to (Result.Height-1) div Cell-1 do
 for j:=0 to (Result.Width-1) div Cell-1 do
 begin
  c:=0;
  inc(n);
  if i*((Result.Height-1) div Cell-1)+j=5 then n:=0;
  for k:=i*Cell to (i+1)*Cell-1 do
  for l:=j*Cell to (j+1)*Cell-1 do
  if k+l<>0 then
  begin
   inc(c,XP[k,l].r);
   inc(c,XP[k,l].g);
   inc(c,XP[k,l].b);
  end;
  s:=c;
  if i*((Result.Height-1) div Cell-1)+j>4 then
  begin
   if n>Size then break;
   c:=Info[n]-c mod 256;
   if i+j=0 then
   if s+c>(Cell*Cell-1)*255*3 then
   c:=c-256;
   if i+j<>0 then
   if s+c>(Cell*Cell)*255*3 then
   c:=c-256;
   if s+c<0 then
   c:=c+256;
  end else
  begin
   c:=bsize[n]-c mod 256;
   if i+j=0 then
   if s+c>(Cell*Cell-1)*255*3 then
   c:=c-256;
   if i+j<>0 then
   if s+c>(Cell*Cell)*255*3 then
   c:=c-256;
   if s+c<0 then
   c:=c+256;
  end;
  Repeat
   for k:=i*Cell to (i+1)*Cell-1 do
   for l:=j*Cell to (j+1)*Cell-1 do
   if k+l<>0 then
   SetPixel(@XP[k,l],c);
  Until c=0;
  for k:=i*Cell to (i+1)*Cell-1 do
  for l:=j*Cell to (j+1)*Cell-1 do
  if k+l<>0 then
  begin
   inc(c,XP[k,l].r);
   inc(c,XP[k,l].g);
   inc(c,XP[k,l].b);
  end;
 end;
end;

Function LoadInfoFromBitmap(Bitmap : TBitmap) : TArByte;
var
  i, j, c, k, l, n, Size, Cell : integer;
  XP : array of PARGB;
  bsize : array[1..5] of byte;
begin
 Result:=nil;
 SetLength(XP,Bitmap.Height);
 for i:=0 to Bitmap.Height-1 do
 XP[i]:=Bitmap.ScanLine[i];
 n:=0;
 bsize[1]:=(XP[0,0].r+XP[0,0].g+XP[0,0].b) mod 24;
 Cell:=bsize[1];
 Cell:=Max(bsize[1],0);
 Cell:=Min(bsize[1],24);
 for i:=0 to (Bitmap.Height-1) div Cell-1 do
 for j:=0 to (Bitmap.width-1) div Cell-1 do
 begin
  c:=0;
  inc(n);
  for k:=i*Cell to (i+1)*Cell-1 do
  for l:=j*Cell to (j+1)*Cell-1 do
  if k+l<>0 then
  begin
   inc(c,XP[k,l].r);
   inc(c,XP[k,l].g);
   inc(c,XP[k,l].b);
  end;
  if i*((Bitmap.Height-1) div Cell-1)+j>4 then
  begin
   if n>Size then Exit;
   Result[n-1]:=c mod 256;
  end else
  begin
   bsize[n]:=c mod 256;
  end;
  if i*((Bitmap.Height-1) div Cell-1)+j=4 then
  begin
   Size:=bsize[2]+bsize[3]*256+bsize[4]*256*256+bsize[5]*256*256*256;
   if Size>1024*1024 then Exit;
   if Size<=0 then Exit;
   SetLength(Result,Min(Size,((Bitmap.Height-1) div Cell-1)*((Bitmap.width-1) div Cell-1)));
   n:=0;
  end;
 end;
end;

Function LoadStringFromInfo(Info : TArByte) : String;
var
  i : integer;
begin
 Result:='';
 For i:=0 to Length(Info)-1 do
 Result:=Result+Char(Info[i]);
end;

Function LoadInfoFromString(Str : String) : TArByte;
var
  i : integer;
begin
 SetLength(Result,Length(Str));
 For i:=1 to Length(Str) do
 Result[i-1]:=Byte(Str[i]);
end;

Function MaxSizeInfoInGraphic(Graphic : TGraphic; Cell : Integer) : Integer;
begin
 Result:=((Graphic.Height-1) div Cell-1)*((Graphic.Width-1) div Cell-1)-5;
end;

Function SaveFileToInfo(FileName : String) : TArByte;
var
  fs : TFileStream;
  Size : Integer;
  i : integer;
begin
 Result:=nil;
 if not fileexists(FileName) then exit;
 Size:=GetFileSizeByName(FileName);
 try
  fs:=Tfilestream.Create( FileName, fmOpenRead    );
 except
  exit;
 end;
 fs.seek(0,soBeginning);
 SetLength(Result,Size+255);
 fs.Read(Pointer(Result)^,Size);
 FileName:=GetFileName(FileName);
 for i:=Size to Size+254 do
 Result[i]:=0;
 for i:=Size to Size+Min(254,Length(FileName)) do
 Result[i]:=Byte(FileName[i-Size+1]);
 fs.free;
end;

Function GetFileNameFromInfo(Info : TArByte) : String;
var
  i, Size : integer;
begin
 Result:='';
 Size:=Length(Info)-256;
 for i:=1 to 255 do
 if Info[i+Size]<>0 then Result:=Result+Char(Info[Size+i]) else break;
end;

Procedure SaveInfoToFile(Info : TArByte; FileName : String);
var
  fs:Tfilestream;
begin
 try
 fs:=Tfilestream.Create(filename,fmOpenWrite or fmCreate);
 except
  exit;
 end;
 fs.Write(Pointer(Info)^,Length(Info)-255);
 fs.free;
end;

function GetMaxPixelsInSquare(FileName : String; Graphic : TGraphic) : integer;
var
  i, FileSize : integer;
begin
 FileSize:=GetFileSizeByName(FileName)+255;
 for i:=3 to 23 do
 begin
  Result:=i;
  if MaxSizeInfoInGraphic(Graphic,i)<FileSize then
  begin
   Result:=i-1;
   break;
  end;
 end;
 if Result<2 then Result:=-1;
end;

end.



Вот так можно выудить файл (ЛЮБОЙ) из битмапки:
Код

var
  Bitmap : TBitmap;
  info : TArByte;
  S : String;
begin
 Bitmap:=TBitmap.create;
 Bitmap.LoadFromFile(FileName);
 info := LoadInfoFromBitmap(Bitmap);
 if info=nil then Exit;
 S:=GetFileNameFromInfo(info);
 SaveDialog1.FileName:=s;
 if SaveDialog1.Execute then
 begin
  SaveInfoToImage.SaveInfoToFile(info,SaveDialog1.FileName);
 end;
 Bitmap.Free;
end;


А вот так запихнуть её в битмапку:
Код

procedure TForm1.AddFileAndSave1Click(Sender: TObject);
var
  Size : Integer;
  info : TArByte;
  Bitmap : TBitmap;
  n : integer;
  o : TOpenOptions;
  s : string;
begin
 if Image1.Picture.Graphic=nil then
 begin
  OpenImage1Click(Sender);
  If Image1.Picture.Graphic=nil then exit;
 end;
 MaxFileSize:=MaxSizeInfoInGraphic(Image1.Picture.Graphic,2)-255;
 if MaxFileSize<0 then exit;
 o:=OpenDialog1.Options;
 Include(o,ofEnableIncludeNotify);
 Exclude(o,ofOldStyleDialog);
 OpenDialog1.Options:=o;
 OpenDialog1.Filter:='Все файлы (Размер<'+SizeInTextA(MaxFileSize)+')|*?*';
 OpenDialog1.OnIncludeItem:=OpenDialog1IncludeItem;
 if OpenDialog1.Execute then
 begin
  FileName:=OpenDialog1.FileName;
  Size:=GetFileSizeByName(FileName);
  Memo1.Text:=FileName;
  Label5.Caption:='Имя файла = '+SizeInTextA(Size);
  S:=GetFileName(PictureFileName);
  s:=GetDirectory(s)+GetFileNameWithoutExt(S)+'.bmp';
  SavePictureDialog1.FileName:=s;
  if SavePictureDialog1.Execute then
  begin
   if GetExt(SavePictureDialog1.FileName)<>'BMP' then
   SavePictureDialog1.FileName:=SavePictureDialog1.FileName+'.bmp';
   info:=SaveFileToInfo(FileName);
   n:=GetMaxPixelsInSquare(FileName,Image1.Picture.Graphic);
   if n<0 then
   begin
    ShowMessage('Файл слишком большой!');
    exit;
   end;
   Bitmap:=SaveInfoToBmpFile(Image1.Picture.Graphic,info,n);
   if Bitmap=nil then exit;
   Bitmap.SaveToFile(SavePictureDialog1.FileName);
   Bitmap.Free;
  end;
 end;
end;



--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
HackMan
Дата 16.7.2005, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Юзверь-программист
**


Профиль
Группа: Участник
Сообщений: 391
Регистрация: 18.6.2005
Где: .ua

Репутация: нет
Всего: 9



Illusion Dolphin
Большое спасибо!
Я сегодня тоже добрый.
С меня бутылка пива smile


--------------------

Завтра - это самый загруженный день недели smile

user posted image

user posted image
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.0763 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.