Steganografie Si Watermarking

CAPITOLUL I

STEGANOGRAFIE ȘI WATERMARKING

1.1 Introducere în steganografie

1.2 Introducere în watermarking

CAPITOLUL II

REPREZENTAREA NUMERICĂ A IMAGINILOR

CAPITOLUL III

FORMATUL BMP (bitmap)

3.1 Structura BMP

3.2 Componentele structurii BMP

3.3 Compresia BMP

CAPITOLUL IV

ASCUNDEREA UNOR INFORMAȚII ÎN IMAGINI

4.1 Algoritmul de ascundere a unor informații în spatele unor imagini

4.2 Rezultatele obținute în urma rulării algoritmului

4.3 Algoritmul de transformare a unei imagini RGB în nuanțe de gri

CAPITOLUL V

MARCAREA VIZIBILĂ ȘI DEMARCAREA UNOR IMAGINI

5.1 Algoritmul de marcare vizibilă a unor imagini

5.2. Algoritmul pentru marcarea vizibilă fixă a unor imagini

Algoritmul de demarcare vizibilă a unor imagini

5.4 Algoritmul de comparare a imaginii originale cu imaginea demarcată

5.5 Rezultatele obținute în urma rulării algoritmilor

CAPITOLUL VI

FIABILITATE SOFTWARE

6.1 Metode de realizare a software-ului fiabil

6.2.Nivele prescrise de fiabilitate

48 pagini

ANEXA I – liniile de program facute automat de limbajul de programare

ANEXA II – prezentarea funcțiilor implementate

ANEXA III – prezentarea butonelor care apar în interfața programului

+ aplicatia ( 82 MB)

ANEXE

ANEXA I – liniile de program facute automat de limbajul de programare

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ExtDlgs,math, Buttons, ExtCtrls, ComCtrls,IdGlobal;

type

TForm1 = class(TForm)

OpenPictureDialog1: TOpenPictureDialog;

GroupBox1: TGroupBox;

Label2: TLabel;

Label3: TLabel;

BitBtn1: TBitBtn;

BitBtn2: TBitBtn;

BitBtn3: TBitBtn;

BitBtn4: TBitBtn;

BitBtn5: TBitBtn;

Image1: TImage;

TabSheet1: TTabSheet;

TabSheet2: TTabSheet;

Memo1: TMemo;

Memo2: TMemo;

Label4: TLabel;

BitBtn6: TBitBtn;

OpenPictureDialog2: TOpenDialog;

Button2: TButton;

Memo4: TMemo;

TabSheet3: TTabSheet;

OpenPictureDialog3: TOpenPictureDialog;

Button1: TButton;

Image2: TImage;

Label6: TLabel;

Button3: TButton;

SaveDialog1: TSaveDialog;

SavePictureDialog1: TSavePictureDialog;

SavePictureDialog2: TSavePictureDialog;

Button4: TButton;

SavePictureDialog3: TSavePictureDialog;

SavePictureDialog4: TSavePictureDialog;

Button5: TButton;

SavePictureDialog5: TSavePictureDialog;

Memo3: TMemo;

Button6: TButton;

Button7: TButton;

pc1: TPageControl;

Label9: TLabel;

Memo5: TMemo;

Memo6: TMemo;

Memo7: TMemo;

Button8: TButton;

procedure Memo1Change(Sender: TObject);

procedure BitBtn1Click(Sender: TObject);

procedure BitBtn2Click(Sender: TObject);

procedure BitBtn3Click(Sender: TObject);

procedure BitBtn5Click(Sender: TObject);

procedure BitBtn4Click(Sender: TObject);

procedure BitBtn6Click(Sender: TObject);

procedure FormActivate(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure Button1Click(Sender: TObject);

procedure Button3Click(Sender: TObject);

procedure Button4Click(Sender: TObject);

procedure Button5Click(Sender: TObject);

procedure Button6Click(Sender: TObject);

procedure Button7Click(Sender: TObject);

procedure Button8Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

caractereDeAscuns:longint;

implementation

uses Unit2;

{$R *.DFM}

ANEXA II – prezentarea funcțiilor implementate de mine

function putere(baza,put:integer):longint;

var i,rez:integer;

begin

rez:=baza;

if (put>1) then

for i:=1 to put-1 do

rez:=rez*baza;

if put=0 then rez:=1;

Result:=rez;

end;

// putere(2,8):=256;

function BinarToString(binar:string):string;

var s:string;

aux:integer;

i,k:integer;

begin

s:='';

k:=0;

while k*8<length(binar) do

begin

aux:=0;

for i:=1 to 8 do

begin

aux:=aux+StrToInt(binar[(k*8)+i])*putere(2,(8-i));

end;

s:=s+char(aux);

inc(k);

end;

Result:=s;

end;

//BinarToString(‘01000010’):= B

function CharToBinar(car:integer):string;

var binar,binarI:string;

j,i,aux:integer;

begin

binar:='';

binarI:='';

while (car>=2) do begin

aux:=car mod 2;

binarI:=binarI+IntToStr(aux);

car:=car div 2;

end;

binarI:=binarI+IntToStr(car);

if (length(binarI)<8) then

for j:=length(binarI)+1 to 8 do

binarI:=binarI+'0';

for i:=length(binarI) downto 1 do

binar:=binar+binarI[i];

Result:=binar;

end;

// CharToBinar(35):= 00010011;

function StringToBinar(s:String):string;

var binar:String;

i:integer;

begin

binar:='';

for i:=1 to length(s) do begin

binar:=binar+CharToBinar(ord(s[i]));

end;

Result:=binar;

end;

//StringToBinar(‘11’):= 0011000100110001;

ANEXA III – prezentarea butonelor care apar în interfața programului

//Functia pentru butonul : Deschideti o imagine

procedure TForm1.BitBtn1Click(Sender: TObject);

var

f: file of Byte;

size : Longint;

textS,cod: string;

i: Integer;

d,c,n1,n2,n3,n4:Byte;

n:integer;

begin

memo3.visible:=false;

button2.visible:=false;

OpenPictureDialog1.FileName:='';

if OpenPictureDialog1.Execute then

begin

memo4.Lines.Clear();

AssignFile(f, OpenPictureDialog1.FileName);

Reset(f);

memo5.Text:='';

form1.Label2.Caption:='';

form1.Label3.Caption:='';

form1.Label4.Caption:='';

form1.Label9.Caption:='';

form1.Label6.Caption:='';

memo6.Text:='';

Button4.Visible:=true;

Button8.Visible:=true;

GroupBox1.Visible:=true;

memo1.Visible:=true;

Label2.Visible:=true;

Label3.Visible:=true;

Label9.Visible:=true;

Label6.Visible:=true;

pc1.Visible:=true;

form1.Memo2.Visible:=false;

form1.Memo1.Enabled:=false;

form1.BitBtn2.Visible:=false;

form1.BitBtn3.visible:=false;

size := FileSize(f);

Seek(f,28);

read(f,c);

memo1.Text:='';

if (c<>24) then begin MessageBox(0,'Imaginea trebuie salvata pe 24 biti', 'Eroare', MB_ICONERROR or MB_OK);

GroupBox1.Visible:=false;

pc1.Visible:=false;

end else begin

Seek(f,6);

read(f,n1);

Seek(f,7);

read(f,n2);

Seek(f,8);

read(f,n3);

Seek(f,9);

read(f,n4);

n:=n1*putere(255,3)+n2*putere(255,2)+n3*putere(255,1)+n4;

caractereDeAscuns:=(size-54)div 8;

if (n<>0) then begin

for i:=1 to n*8 do begin

Seek(f,53+i);

read(f,d);

cod:=cod+IntToStr(d mod 2);

end;

textS:=BinarToString(cod);

if ((textS[1]<>'*') and (textS[2]<>'$') and (textS[3]<>'&')) then begin

memo6.Text:='Imaginea contine ascuns fisierul: ';

pc1.ActivePageIndex:=1;

memo4.visible:=true;

button2.visible:=true;

memo4.Lines.Clear();

memo4.Lines.Add(textS);

BitBtn3.visible:=true

end else begin

pc1.ActivePageIndex:=0;

form1.Label4.Caption:='Imaginea contine ascuns textul: ';

form1.Memo2.Visible:=true;

form1.BitBtn3.visible:=true;

textS:=copy(textS,4,length(textS)-3);

form1.Memo2.text:=textS;

memo4.Lines.Clear();

end;

end;

BitBtn2.Visible:=true;

form1.Memo1.Enabled:=true;

form1.Memo1.MaxLength:=(caractereDeAscuns);

memo5.Text:='Nume imagine: '+OpenPictureDialog1.FileName;

form1.Label2.Caption:='Dimensiune imagine: '+IntToStr(size)+' bytes';

form1.Label3.Caption:='Numar caractere ce pot fi ascunse: '+IntToStr(caractereDeAscuns);

end;

CloseFile(f);

Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName)

end;

end;

//Functia pentru afisarea pe ecran a numarului de caractere introduse si ramase

procedure TForm1.Memo1Change(Sender: TObject);

Label9.Caption:='Caractere folosite :'+IntToStr(length(memo1.text));

Label6.Caption:='Caractere ramase :'+IntToStr(caractereDeAscuns-length(memo1.text));

end;

//Functia pentru butonul Deschide un fisier text

procedure TForm1.BitBtn6Click(Sender: TObject);

begin

if OpenPictureDialog2.Execute then

begin

Label7.caption:='S-a deschis fisierul '+OpenPictureDialog2.FileName;

end;

end;

//Functia pentru butonul: Ascunde text /fisier

procedure TForm1.BitBtn2Click(Sender: TObject);

var

f: file of Byte;

g:file of Byte;

c,zero:Byte;

dim:integer;

textdeascuns:string;

i:integer;

mask:byte;

size:longint;

begin

label9.Visible:=false;

label6.Visible:=false;

mask:=1;

zero:=0;

form1.Label4.Caption:='Imaginea contine ascuns textul: ';

form1.Memo2.Visible:=true;

form1.Memo2.text:=memo1.Text;

form1.Memo3.Visible:=true;

form1.BitBtn3.visible:=true;

memo6.Text:=IntTostr(pc1.ActivePageIndex);

textdeascuns:='';

if (pc1.ActivePageIndex=0) then begin

textdeascuns:=StringToBinar('*$&'+memo1.Text);

end

else begin

if (form1.OpenPictureDialog2.FileName='') then begin

MessageBox(0, 'Deschideti ma intai fisierul pe care vreti sa-l ascundeti', 'Eroare', MB_ICONERROR or MB_OK)

end else begin

AssignFile(g, form1.OpenPictureDialog2.FileName);

reset(g);

size := FileSize(g);

if ((size>(caractereDeAscuns))) then begin

MessageBox(0, 'Fisierul este prea mare pentru a putea fi ascuns in aceasta imagine', 'Eroare', MB_ICONERROR or MB_OK)

end else begin

while (not(eof(g))) do begin

read(g,c);

textdeascuns:=textdeascuns+StringToBinar(char(c));

end;

memo4.Visible:=true;

button2.Visible:=true;

memo6.Text:='Imaginea contine ascuns fisierul: ';

end;

CloseFile(g);

memo4.lines.LoadFromFile(form1.OpenPictureDialog2.FileName);

end;

end;

if (textdeascuns<>'') then begin

SavePictureDialog4.FileName:='';

SavePictureDialog4.Execute;

if (SavePictureDialog4.FileName<>'') then begin

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog4.FileName);

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

AssignFile(f, SavePictureDialog4.FileName);

Reset(f);

dim:=length(textdeascuns) div 8;

Seek(f,6);

if (dim div putere(255,3)>0) then begin

c:=dim div putere(255,3);

Write(f,c);

dim:=dim mod putere(255,3);

end else Write(f,zero);

Seek(f,7);

if (dim div putere(255,2)>0) then begin

c:=dim div putere(255,2);

Write(f,c);

dim:=dim mod putere(255,2);

end else Write(f,zero);

Seek(f,8);

if (dim div putere(255,1)>0) then begin

c:=dim div 255;

Write(f,c);

dim:=dim mod 255;

end else Write(f,zero);

Seek(f,9);

Write(f,dim);

for i:=1 to length(textdeascuns) do begin

Seek(f,53+i);

Read(f,c);

if (textdeascuns[i]='0')and(c mod 2 <>0) then c:=c xor mask;

if (textdeascuns[i]='1')and(c mod 2 <>1) then c:=c xor mask;

Seek(f,53+i);

Write(f,c);

end;

CloseFile(f);

form1.Memo3.text:=textdeascuns;

end;

end;

end;

//Functia pentru butonul Salveaza fisierul

procedure TForm1.Button2Click(Sender: TObject);

begin

SaveDialog1.Execute;

if (SaveDialog1.FileName<>'') then begin

memo4.Lines.SaveToFile(SaveDialog1.FileName);

MessageBox(0, 'Textul a fost salvat', 'Confirmare', MB_ICONinformation or MB_OK)

end;

end;

//Functia pentru butonul Sterge text/fisier

procedure TForm1.BitBtn3Click(Sender: TObject);

var

f: file of Byte;

c:Byte;

begin

memo4.Lines.Clear;

SavePictureDialog2.FileName:='';

SavePictureDialog2.Execute;

if (SavePictureDialog2.FileName<>'') then begin

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog2.FileName);

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

AssignFile(f, form1.SavePictureDialog2.FileName);

Reset(f);

c:=0;

Seek(f,6);

Write(f,c);

Seek(f,7);

Write(f,c);

Seek(f,8);

Write(f,c);

Seek(f,9);

Write(f,c);

CloseFile(f);

form1.BitBtn3.visible:=false;

form1.Label4.Caption:='';

memo6.Text:='';

form1.Memo2.Visible:=false;

form1.Memo2.text:='';

end;

end;

//Functia pentru butonul Deschide marca

procedure TForm1.Button1Click(Sender: TObject);

begin

if OpenPictureDialog3.Execute then

begin

Button3.Visible:=true;

Button4.Visible:=true;

Button5.Visible:=true;

Button6.Visible:=true;

Button7.Visible:=true;

memo7.Text:='S-a deschis imaginea: ' + OpenPictureDialog3.FileName;

Image2.Picture.LoadFromFile(OpenPictureDialog3.FileName);

end;

end;

//Functia pentru butonul Marcheaza imaginea

procedure TForm1.Button5Click(Sender: TObject);

var

x1:file of Byte;

x2:file of Byte;

c2:Byte;

j:integer;

v123:byte;

vInt:integer;

begin

if ((image1.Picture.Height<image2.Picture.Height) or (image1.Picture.Width<image2.Picture.Width)) then begin

MessageBox(0, 'Imaginile nu sunt compatibile', 'Eroare', MB_ICONERROR or MB_OK);

end else begin

SavePictureDialog5.FileName:='';

SavePictureDialog5.Execute;

if (SavePictureDialog5.FileName<>'') then begin

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog5.FileName);

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

AssignFile(x1, SavePictureDialog5.FileName);

AssignFile(x2, form1.OpenPictureDialog3.FileName);

Reset(x1);

Reset(x2);

j:=0;

while (not(eof(x2))) do begin

read(x2,c2);

if ((j>=54) and (c2=0)) then begin

seek(x1,53+image1.Picture.Width*((j-53-1) div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));

read(x1,v123);

vInt:=v123;

if (vInt+20>255) then begin

v123:=255;

end else v123:=v123+20;

seek(x1,53+image1.Picture.Width*((j-53-1) div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));

write(x1,v123);

end;

inc(j);

end;

closefile(x1);

closefile(x2);

Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);

end;

end;

end;

//Functia pentru butonul Scoate marca

procedure TForm1.Button3Click(Sender: TObject);

var

x1:file of Byte;

x2:file of Byte;

v123,c2:Byte;

j:integer;

begin

if ((image1.Picture.Height<image2.Picture.Height) or (image1.Picture.Width<image2.Picture.Width)) then begin

MessageBox(0, 'Imaginile nu sunt compatibile', 'Eroare', MB_ICONERROR or MB_OK);

end else begin

SavePictureDialog1.FileName:='';

SavePictureDialog1.Execute;

if (SavePictureDialog1.FileName<>'') then begin

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog1.FileName);

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

AssignFile(x1, form1.SavePictureDialog1.FileName);

AssignFile(x2, form1.OpenPictureDialog3.FileName);

Reset(x1);

Reset(x2);

j:=0;

while (not(eof(x2))) do begin

read(x2,c2);

if ((j>=54) and (c2=0)) then begin

seek(x1,53+image1.Picture.Width*((j-53-1) div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));

read(x1,v123);

if (v123=255) then begin

v123:=250;

end else

v123:=v123-20;

seek(x1,53+image1.Picture.Width*((j-53-1) div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));

write(x1,v123);

end;

inc(j);

end;

closefile(x1);

closefile(x2);

Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);

end;

end;

end;

//Functia pentru butonul Transforma imaginea in nuante de gri

procedure TForm1.Button4Click(Sender: TObject);

var

x1:file of Byte;

c1,c2,c3,c:Byte;

j:integer;

begin

SavePictureDialog3.FileName:='';

SavePictureDialog3.Execute;

if (SavePictureDialog3.FileName<>'') then begin

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog3.FileName);

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

AssignFile(x1, form1.SavePictureDialog3.FileName);

Reset(x1);

j:=0;

while (not(eof(x1))) do begin

if ((j>=54)and ((j-54) mod 3 =0)) then begin

seek(x1,j);

read(x1,c1);

seek(x1,j+1);

read(x1,c2);

seek(x1,j+2);

read(x1,c3);

c:=round((c1+c2+c3)/3);

seek(x1,j);

write(x1,c);

seek(x1,j+1);

write(x1,c);

seek(x1,j+2);

write(x1,c);

end;

inc(j);

end;

closefile(x1);

Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);

end;

end;

procedure TForm1.FormActivate(Sender: TObject);

begin

label6.Caption:='';

label8.Caption:='';

memo4.visible:=false;

button2.visible:=false;

end;

//Functia pentru butonul Deschide imaginea demarcata

procedure TForm1.Button9Click(Sender: TObject);

begin

if OpenPictureDialog3.Execute then

begin

Button7.Visible:=true;

Button8.Visible:=false;

BitBtn2.visible:=false;

memo3.Visible:=true;

memo8.Text:='S-a deschis imaginea demarcata: ' + OpenPictureDialog3.FileName;

Image4.Picture.LoadFromFile(OpenPictureDialog3.FileName);

end;

end;

end.

//Functia pentru butonul Marcare fixa

procedure TForm1.Button6Click(Sender: TObject);

var

x1:file of Byte;

x2:file of Byte;

c2:Byte;

j:integer;

v123:byte;

begin

if ((image1.Picture.Height<image2.Picture.Height) or (image1.Picture.Width<image2.Picture.Width)) then begin

MessageBox(0, 'Imaginile nu sunt compatibile', 'Eroare', MB_ICONERROR or MB_OK);

end else begin

SavePictureDialog5.FileName:='';

SavePictureDialog5.Execute;

if (SavePictureDialog5.FileName<>'') then begin

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog5.FileName);

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

AssignFile(x1, SavePictureDialog5.FileName);

AssignFile(x2, form1.OpenPictureDialog3.FileName);

Reset(x1);

Reset(x2);

j:=0;

while (not(eof(x2))) do begin

read(x2,c2);

if ((j>=54) and (c2=0)) then begin

seek(x1,53+image1.Picture.Width*((j-53-1) div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));

read(x1,v123);

v123:=200;

seek(x1,53+image1.Picture.Width*((j-53-1) div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));

write(x1,v123);

end;

inc(j);

end;

closefile(x1);

closefile(x2);

Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);

end;

end;

end;

//Functia pentru butonul Compara imaginile

procedure TForm1.Button7Click(Sender: TObject);

var

x1:file of Byte;

x2:file of Byte;

c1:Byte;

c2:Byte;

dif:Integer;

antet:Integer;

begin

memo3.Visible:=true;

AssignFile(x1, form1.OpenPictureDialog1.FileName);

AssignFile(x2, form1.OpenPictureDialog3.FileName);

reset(x1);

reset(x2);

dif:=0;

antet:=54;

while (not(eof(x2))) do begin

seek(x1,antet);

seek(x2,antet);

read(x1,c1);

read(x2,c2);

if c1<>c2 then begin

inc(dif);

end;

inc(antet);

end;

closefile(x1);

closefile(x2);

form1.Memo3.text:= 'Imaginile au :' + IntToStr(dif) + ' octeti diferiti' ;

end;

//Functia pentru butonul Ascunde numarul de caractere

procedure TForm1.Button8Click(Sender: TObject);

var

c,zero:Byte;

dim:integer;

f:file of byte;

begin

zero:=0;

try

dim:=StrToInt(memo1.Text);

if (dim>caractereDeAscuns) then begin

MessageBox(0,'Numarul este prea mare.', 'Eroare', MB_ICONERROR or MB_OK);

end

else begin

AssignFile(f, OpenPictureDialog1.FileName);

Reset(f);

Seek(f,6);

if (dim div putere(255,3)>0) then begin

c:=dim div putere(255,3);

Write(f,c);

dim:=dim mod putere(255,3);

end else Write(f,zero);

Seek(f,7);

if (dim div putere(255,2)>0) then begin

c:=dim div putere(255,2);

Write(f,c);

dim:=dim mod putere(255,2);

end else Write(f,zero);

Seek(f,8);

if (dim div putere(255,1)>0) then begin

c:=dim div 255;

Write(f,c);

dim:=dim mod 255;

end else Write(f,zero);

Seek(f,9);

Write(f,dim);

CloseFile(f);

end;

except

MessageBox(0,'Numarul introdus nu este valid.', 'Eroare', MB_ICONERROR or MB_OK);

end;

end;

//Functia pentru butonul Informatii

procedure TForm1.BitBtn4Click(Sender: TObject);

begin

form2.Left:=form1.left+63;

form2.Top:=form1.top+69;

form2.Visible:=true;

end;

//Functia pentru butonul Inchide

procedure TForm1.BitBtn5Click(Sender: TObject);

begin

application.Terminate;

end;

=== Capitolul I ===

CAPITOLUL I

STEGANOGRAFIE ȘI WATERMARKING

1.1 Introducere în steganografie

Derivat din limba greacă, cuvântul steganografie înseamnă „scriere ascunsă", o colecție de tehnici dedicate camuflării unui mesaj astfel încât, chiar dacă mediul de comunicație este interceptat, existența vreunui alt transport de informație decât cel implicit al mediului sa fie nedetectabilă. Folosind steganografia informația poate fi ascunsă în purtători ca: imagini, fișiere audio, fișiere text, transmisiuni video și de date. Când mesajul este ascuns în purtător se formează un stego-purtător. Formatul datelor celor mai des utilizate sunt: .BMP, .JPEG, .mp3, .txt și .wav.

Steganografia reprezintă metoda de a ascunde un mesaj (criptat sau nu) într-un obiect de alt tip (imagini, sunete etc.). În acest caz descifrarea mesajului devine mult mai dificilă pentru o persoană straină întrucât implică și descoperirea suportului și, în cadrul suportului, a mesajului. Combinația între criptare și steganografie permite și folosirea unui sistem de securitate deschis (de exemplu publicarea mesajelor pe un site WEB prin ascunderea acestuia sub o imagine) securitatea asigurată de acest sistem făcând practic imposibilă descifrarea mesajului de către o terță parte.

Steganografia, nu înlocuiește criptografia, ea oferind încă un strat de protecție dacă acestea două sunt folosite împreună.

Steganografia diferă de criptografie prin faptul că ținta acesteia este de a ascunde existența unui mesaj, în timp ce țelul criptografiei este de a dezvălui înțelesul mesajului.

Importanța steganografiei, a fost evidențiată mai ales în timpul războaielor, ea fiind folosită de sute de ani, sub diferite forme. Herodot este printre primii istorici care menționează o tehnică steganografică: Demeratus dorea să îi avertizeze pe spartani că Xerxes plănuia invadarea Greciei. Pentru a nu avea surprize la graniță, tableta de lemn acoperită cu ceara – folosită curent de curieri – a fost razuită de stratul moale de ceară, mesajul a fost incizat în lemn, iar tableta a fost reacoperită cu ceară, părând nefolosită. Solul a scăpat, altfel nu se auzea de el… Ulterior, tableta a fost înlocuită cu… capul solului: acesta era ras, pe piele se inscripționa mesajul apoi părul era lăsat să crească, acoperind complet literele. Solul probabil mergea regulat pentru un „tuns zero" în regatul vecin!

Inventarea cernelurilor simpatice, vizibile doar în ultraviolet sau dupa o developare, a deschis un capitol nou în spionaj, și scrisorile inocente purtând între rânduri date secrete au proliferat.

Tot în domeniul textului scris, ascunderea unui mesaj prin crearea unui text ale cărui cuvinte începeau fiecare cu câte o literă a mesajului original a fost o tehnică steganografică larg raspândită, mai ales prin intermediul anunțurilor de mică publicitate prin care spionii aflați dincolo de linia frontului puteau comunica anunțuri scurte. Germanii au mers mai departe, prin dezvoltarea tehnicii micropunctului prin care o întreagă pagină A4 era redusă la dimensiunea unui punct, aplicat ulterior pe un pliant oarecare sau pe colțul lentilei de la ochelari. O altă cale de transmitere a mesajelor, era "spargerea" textelor în litere și punerea lor într-o anumită poziție în cuvinte care formează un text care nu trezește nici o suspiciune. O astfel de tehnică, a fost folosită într-un Null ciphers :

News Eight Weather: Tonight increasing snow. Unexpected precipitation smothers eastern towns. Be extremely cautious and use snowtires especially heading east. The highways is knowingly slippery. Highway evacuation is suspected. Police report emergency situations in downtown ending near Tuesday.

Astfel, dacă se ia prima literă din fiecare cuvânt, se obține mesajul:

Newt is upset because he thinks he is President.

O metodă înrudită cu steganografia este utilizată de câteva decenii în transmisiile radio militare și mai recent și civile: frecvența de comunicație este schimbată, printr-un algoritm pseudo-aleator, de sute sau mii de ori pe secundă. Dacă inamicul ascultă doar anumite frecvențe, indiferent care ar fi acestea, nu va putea detecta prezența vreunei comunicații, căci transmisiile cu spectru împrăștiat (spread spectrum) produc semnale mult mai slabe decât zgomotul inerent prezent pe un canal radio.

Motivul pentru care acest articol apare într-o revistă de informatică este usor de intuit: prelucrarea digitală a adus un impuls extraordinar steganografiei. Mediul preferat de transport a devenit imaginea – și, mai recent, sunetul – din mai multe considerente:

– alterarea ușoară a unui astfel de fișier nu este deranjantă, uneori nici măcar perceptibilă ;

– inserarea/extragerea mesajului ascuns este o sarcină banală din punct de vedere algoritmic și schimbul de imagini este o activitate extrem de raspândită și, ca atare, un mediu ideal pentru steganografie.

Steganografia algoritmică folosește cel mai adesea drept suport fișiere imagine sau audio, speculând imperfecțiunile organelor umane de simț. O imagine obișnuită în tonuri de gri (grayscale) utilizează un octet / pixel pentru păstrarea nivelului de gri. Considerând mesajul secret ca un șir de biți (nu de octeți), am putea stoca fiecare dintre acești biți în cel mai puțin semnificativ bit (LSB) al fiecărui pixel.

Astfel, nivelul de gri este modificat cu cel mult o treaptă (din maximum 256 posibile), modificare prea mică pentru a fi sesizabilă, mai ales în lipsa originalului.

Fișierele grayscale sau cele indexate cu 256 de culori pot ascunde un număr de biți egal cu numărul pixelilor. O imagine RGB, având 3 octeti/pixel, are o capacitate de stocare triplă. Atenție însă la formatul ales pentru transportul imaginilor, mai ales prin Internet unde se dorește reducerea la minim a mărimii fișierului: un format popular pentru imagini RGB/grayscale este JPEG pentru că ratele de compresie sunt foarte mari. Formatul JPEG este total contraindicat steganografiei bazată pe codarea în cel mai puțin semnificativ bit din pixel, deoarece compresia utilizată de algoritmul JPEG este una care folosește aproximații, imaginea decomprimată fiind diferită de cea originală.

Tehnologiile steganografice sunt o parte foarte importantă a viitorului securității Internet-ului pentru sisteme deschise ca acesta. Cercetarea steganografică este condusă înainte de toate de lipsa de tărie din sistemele criptografice și din dorința de a întări pe cât posibil sistemul secretizării din sistemele deschise. Astăzi, cercetările steganografice sunt conduse în multe scopuri.

Sunt multe potențiale aplicații pentru steganografie, aplicațiile militare fiind ele însele evidente.

Tehnicile steganografice sunt esențiale mai ales în operațiunile ”sub acoperire”. În multe țări, criptarea este ilegală, uneori cu penalizare prin moarte. Fără criptare guvernul poate monitoriza toate datele schimbate prin formatul electronic.

1.2 Introducere în watermarking

Ușurința cu care informația digitală este distribuită, editată și copiată cu înaltă fidelitate, a dus la necesitatea proiectării unor instrumente de protecție a informației, cunoscute sub numele de copyright tools. Acestea ascund informația (datele) din fișierele ce conțin informație audio, imagini sau video. O cale de ascundere este folosirea unei semnături digitale (numerice), o etichetă de protecție (copyright label) sau o mască (marker) digitală (digital watermark). Mascarea numerică (Digital watermarking) este procesul care ascunde anumite date numite watermark într-un obiect multimedia astfel încât acest watermark să poată fi detectat și extras mai târziu. Tehnica de mascare poate fi vizibilă sau invizibilă.

Tehnica „watermarking” înseamnă suprapunerea unei imagini, semn sau marker peste mesajul util. Se va folosi numele de marcare, ca sinonim în limba romană al tehnicii de watermarking, folosit în limba engleză.

Istoria ascunderii informației

Tehnica watermarking a evoluat din steganografie. Utilizarea tehnicii watermarking este folosită încă din momentul începerii fabricației hârtiei. Tehnica watermarking înseamnă impresionarea hârtiei cu o formă de imagine sau text, în timpul procesului de fabricație al hârtiei. Prin aceasta tehnică se inscripționează marca producătorului, astfel încât autenticitatea poate fi ușor stabilită fără degradarea esteticii și utilității stocului. Recent, tehnica WM (watermarking) este folosită pentru certificarea compoziției hârtiei, incluzând natura fibrelor folosite.

Digitizarea documentelor și a comunicațiilor a făcut ca acestă tehnică să includă impresii digitale pentru autentificarea proprietarului și a drepturilor de autor. În principiu, tehnica watermark este la fel ca în cazul hârtiei. Diferite grade de WM adăugate mijloacelor de prezentare garantează autentificarea, calitatatea producătorului și a sursei.

WM este procesul care ascunde datele numite watermark sau o etichetă într-un obiect multi-media astfel încât WM poate fi detectat sau extras mai târziu pentru a clasifica obiectul respectiv. Obiectul poate fi o imagine sau audio sau video sau text.

Steganografia vs watermarking

Ele diferă în primul rând prin intenția de utilizare. Un WM poate fi perceput ca un atribut al purtătorului (cover). Poate conține informație despre copyright, licență, autor, proprietar etc. În cazul steganografiei, mesajul ascuns poate să nu aibă nici o legatură cu purtătorul.

Introducere în WM numerică

Tehnologia WM reunește domeniile teoretice și practice ale calculatoarelor, criptografie, prelucrarea semnalelor și comunicațiilor. Wm numerică se dorește să protejeze datele în scopul criptării datelor pentru protecție. Ca și alte tehnologii în dezvoltare WM atrage o serie de întrebări esențiale, cum ar fi: Cum poate fi WM inserată și detectată? Cât de robustă trebuie să fie? De ce și când este necesară? Ce fel de WM trebuie utilizată? Cum se poate evalua tehnologia?

Un cadru general pentru WM

WM este procesul care ascunde datele numite watermark într-un obiect multimedia astfel încât WM poate fi detectat sau extras mai târziu pentru a prelucra respectivul obiect. Un exemplu simplu de WM numerică ar fi un sigiliu plasat deasupra imaginii pentru a detecta copyright-ul. Totuși WM poate avea și alte elemente auxiliare cum ar fi identitatea cumpărătorului copiei respective.

În general, orice algoritm (schemă) conține trei părți;

– o mască (watermark);

– un codor (algoritmul de inserție);

– decodorul și comparatorul (algoritmul de verificare sau extragere sau detecție).

Fiecare proprietar/producător (owner) are o mască/marcă proprie sau un producător poate pune diferite mărci în diferite obiecte. Algoritmul de verificare autentifică atât producătorul cât și integritatea obiectului.

O mască trebuie sa fie detectabilă sau extractabilă pentru a fi utilă. Depinzând de modul în care o marcă este utilizată și depinzând de natura algoritmului de marcare, metodele utilizate pot folosi abordări foarte diferite. Unele proceduri permit extragerea în forma exactă a mărcii. În alte cazuri se poate detecta numai prezența mărcii într-un semnal de imagine. Prin extragerea mărcii se poate demonstra proprietarul în timp ce prin detecție se poate verifica proprietarul (ownership).

Tipuri de mărci numerice

Mărcile cât si tehnicile de marcare pot fi clasificate în diverse moduri. Mărcile pot fi aplicate și în domeniul spațial. O alternativă la domeniul marcării spațiale este marcarea în domeniul frecvență. Metodele frecvențiale sunt mai robuste decât tehnicile spațiale.

Tehnicile de marcare pot fi împărțite în patru categorii în raport cu tipul documentului de marcat:

– marcarea imaginilor;

– marcarea video;

– marcarea audio;

– marcarea textului.

În raport cu percepția umană, mărcile digitale pot fi împarțite în urmatoarele trei categorii:

– marcă vizibilă;

– marcă invizibilă și robustă;

– marcă invizibilă fragilă;

– marcă duală.

O marcă vizibilă este un plan/imagine/strat secundar translucid inclus în imaginea primară. Marca apare vizibilă unui utilizator la o inspecție atentă.

O marcă robustă invizibilă este ascunsă astfel încât alternările fac ca valorile alternante ale pixelilor să nu fie percepute decât cu mecanisme de decodare corespunzătoare.

Figura 1– Tipuri de tehnici pentru WM

Din punct de vedere al aplicației, marcarea digitală poate fi bazată pe sursă (source based) sau pe destinație (destination based).

Marcarea bazată pe sursă este de dorit pentru identificarea proprietarului atunci când se introduce o marcă unică pentru identificarea proprietarului în toate copiile unei imagini particulare care este distribuită. O marcă bazată pe sursă poate fi utilizată pentru autentificare și să determine dacă imaginea recepționată sau alte date eletronice au fost alterate cu ea.

Marcarea poate fi de asemenea bazată pe destinatar când fiecare copie pentru distribuție ia o marcă proprie pentru identificarea unui cumpărător particular. O astfel de marcă poate fi utilizată pentru urmărirea cumpărătorului în cazul unor revânzări ilegale.

Aplicațiile marcării digitale

Marcarea vizibilă

Marcarea vizibilă poate fi utilizată la:

– evidențierea protecției de copyright. Se folosește când imaginile sunt disponibile de pe Internet și proprietarul se teme că imaginile vor putea fi folosite în scopuri comerciale fără plata drepturilor de autor. Proprietarul folosește o marcă vizibilă, însă care nu protejează imaginea împotriva folosirii acesteia în alte scopuri.

– indicarea originii proprietarului. În acest caz, imaginile disponibile de pe Internet sunt marcate pentru evidențierea proprietarului, cum este cazul manuscriselor din biblioteci.

Marcarea invizibilă robustă

Se folosește în cazurile/scenariile:

– detecția imaginilor greșit asemănătoare (misappropiated). Vânzătorul imaginii digitale este îngrijorat că alți cumpărători le vor revinde fără plata drepturilor de autor.

– proprietarul imaginii digitale suspectează că imaginile sale au fost editate sau publicate fără plata drepturilor („royalties”). Detecția mărcii vânzătorului în imagine este pusă pentru a evidenția că imaginea publicată este proprietatea vanzătorului.

Marcarea invizibilă fragilă

Aplicațiile sunt:

– marcarea invizibilă pentru autenticitate; imaginile sunt capturate cu o cameră digitală pentru a le include mai târziu în articole de știri. Agenția dorește să verifice că imaginea este aceeași cu imaginea originală și nu a fost editată pentru modificarea scenei. În acest caz, o marcă invizibilă este ascunsă la momentul capturii; prezența sa la momentul publicării este pusă ca să se indice că imaginea nu a fost modificată față de momentul capturării acesteia.

– marcarea invizibilă pentru a detecta alterarea imaginilor din bibliotecile digitale. În acest caz, imaginile digitale (de ex, amprentele) au fost scanate și stocate într-o bibliotecă digitală; conținutul proprietarului decide abilitatea de a detecta orice alterare a imaginii, fără să fie necesară compararea imaginilor cu materialele scanate.

Atacuri ale mărcilor

O imagine marcată poate fi supusă unor prelucrări, intenționate (compresia sau zgomotul de transmisie) sau neintenționate (filtrare):

– compresia cu pierdere de informație: multe scheme de compresie (JPEG sau MPEG) pot să degradeze ireversibil datele despre marcă;

– distorsiunile geometrice: sunt specifice imaginilor video și includ opearații ca rotație, traslație, scalare și ajustare;

– operații simple/tipice de prelucrare a semnalelor: conversie A/D si D/A, reeșantionare, recuantizare, dithering, recompresie, filtrare neliniară (filtrare mediană);

– reducerea culorilor.

– adăugarea unei cantități constante la valorile pixelilor;

– adăugarea unui zgomot gaussian;

– schimbarea locală de pixeli.

Alte atacuri intenționate:

– tipărire și rescanare;

– marcarea unei imagini marcate;

Caracteristici dorite ale mărcilor vizibile:

– o marcă vizibilă trebuie să fie usor de înțeles și priceput în ambele imagini mono și color;

– marca trebuie să se răspândească într-o arie importantă a imaginii în vederea prevenirii

îndepărtării acesteia prin ștergere sau înlocuire;

– marca trebuie să fie vizibilă dar să nu afecteze semnificativ detaliile imaginii marcate;

– marca trebuie să fie dificil de îndepărtat. Mai mult îndepărtarea mărcii trebuie să fie mai

dificilă și mai scumpă decât cumpărarea imaginii respective de la distribuitor;

– marca trebuie aplicată automat fără eforturi deosebite din partea utilizatorului.

=== Capitolul II ===

CAPITOLUL II

REPREZENTAREA NUMERICĂ A IMAGINILOR

O imagine digitală este cel mai folosit purtător pentru steganografie, fiind realizată folosind o cameră, un scanner sau orice alt dispozitiv. Reprezentarea digitală este o aproximație a imaginii original. Sistemul a folosit pentru producerea focarelor imaginii un model bidimensional al variației intensității luminii și culorii pe un instrument de măsură.

O imagine este o suprafață de obicei dreptunghiulară caracterizată, la nivelul oricărui punct al ei, de o anumită culoare. La modul ideal, culoarea variază în mod continuu în oricare direcție. Din păcate, în sistemele numerice, nu se pot utiliza mărimi care variază continuu ci doar forma discretizată a acestora. Discretizarea este operația prin care se reprezintă o mărime cu variație continuă sub forma unui ansamblu finit de eșantioane.

În concluzie, o imagine trebuie să fie discretizată înainte de a se pune problema reprezentării numerice. Discretizarea constă în împărțirea imaginii într-un caroiaj asemănător unei table de șah. Fiecare secțiune de imagine delimitată de acest caroiaj va fi considerată ca având o culoare uniformă – o medie a culorii existente pe această secțiune. Aceste secțiuni mai sunt denumite și pixeli sau puncte, numărul acestora definind rezoluția imaginii. Fiecare pixel este memorat în general pe 24 biți sau 8 biți. Un pixel memorat pe 24 de biți oferă combinații de culoare de .

Astfel se poate afirma, de exemplu, că o imagine oarecare are o rezoluție de 640×480 pixeli ceea ce înseamnă că pe suprafața acesteia s-a definit un caroiaj care o împarte pe orizontală în 640 de secțiuni iar pe verticală în 480. Operația de discretizare a unei imagini este pusă în evidență în imaginea de mai jos care a fost marită în mod special pentru a se putea observa caroiajul.

Pasul următor îl constituie găsirea unei reprezentări pentru culoare. Orice culoare poate fi descompusă în trei culori primare (de exemplu rosu-R, verde-G si albastru-B), cu alte cuvinte orice imagine poate fi obținută prin suprapunerea aditivă a trei radiații luminoase având aceste trei culori și intensități diferite. În figura următoare se prezintă obținerea a câtorva culori prin acest mecanism:

Deci, pentru a reprezenta numeric o culoare este suficient să reprezentăm intensitățile luminoase ale celor trei culori primare. Dacă alocăm câte 8 biți pentru fiecare componentă se pot codifica 256 nivele de intensitate, astfel, absența culorii (intensitate zero) se codifică prin valoarea 00000000 binar (00h) iar intensitatea maximă prin cea mai mare valoare reprezentabilă pe 8 biți și anume 11111111 binar (FFh).

Această reprezentare, însă, ține mai mult de modalitățile tehnice de captare și reproducere a imaginii și mai puțin de mecanismul fiziologic de percepere a culorii. Prin diferite experimente s-a constatat din punct de vedere al capacității de percepere a detaliilor, ochiul este mai sensibil la intensitatea luminoasă a culorii decât la nuanță.

=== Capitolul III ===

CAPITOLUL III

FORMATUL BMP (bitmap)

În ultimii ani formatul BMP a devenit un standard important ca urmare a faptului că este utilizat atât sub OS/2 cât și sub Windows. Pentru mulți dintre noi, acest format este destul de străin având în vedere că îl cunoaștem mai mult după nume și nu neapărat după structură.

Acest format este cel mai utilizat la ora actuală pentru reprezentarea numerică a imaginilor. Sub sistemul de operare OS/2 ca dealtfel și sub Windows, fișierele de format BMP se folosesc pentru a stoca imagini, icon-uri, cursoare, pointeri și poate lista nu este completă.

De fapt sub acest nume se regăsesc mai multe tipuri de formate care au urmărit de fapt evoluția în domeniul dispozitivelor de afișare a imaginii.

Există două versiuni ale formatului BMP sub Windows și două sub OS/2. Putem să le considerăm ca fiind de fapt versiunea veche și versiunea nouă pentru fiecare din cele două platforme. Cele două versiuni vechi sunt identice, lucru explicabil ca urmare a originii comune a lui OS/2 si Windows. Versiunile așa-zise noi ale formatului BMP sunt diferite. Aceasta înseamnă că o aplicație care vrea să lucreze în cazul oricărei instanțe valide de BMP trebuie să ia în considerare trei variante diferite de format.

Din punct de vedere al programatorului, programul trebuie să fie pregătit să interpreteze corect oricare din cele trei versiuni de format BMP iar logica handler-ului de erori trebuie să se ocupe de cel puțin trei situații distincte: un fișier imagine BMP valid, un fișier BMP valid dar care conține altceva decât o imagine, un fișier invalid de format neștiut. În continuare ne vom focaliza atenția asupra formatului BMP pentru imagine și a câtorva informații legate de modul de codificare și decodificare a datelor.

3.1 Structura BMP

Formatul BMP este de uzanță generală astfel încât permite stocarea, într-un fișier pe disc, a unei imagini de orice dimensiune. Informațiile despre culoare pot să varieze de la 1 bit la 24 de biți. De asemenea este suportată codificarea RLE (run length encoding) sub Windows sau comprimarea folosind algoritmul Huffman sub OS/2. Până acum nu am întâlnit nici un fișier având extensia BMP care să folosească una din aceste tehnici de compresie. În ceea ce privește modul de stocare, imaginea este înregistrată linie cu linie pornind de jos în sus. Acest lucru nu prezintă nici o problemă atunci când este necesară afișarea imaginii pe monitor folosind API-ul Windows sau OS/2 (Presentation Manager). Problema reală apare în cazul în care trebuie să ne preocupăm direct de datele stocate în fișier, respectiv atunci când trebuie să facem conversia de format sau trebuie să listăm imaginea respectivă la imprimantă.

În fiecare din cele trei variante specificate, un fișier BMP conține, respectând ordinea apariției, următoarele părți (am dat denumirile în engleză preluate din Microsoft Windows Programmer's Reference pentru a nu exista dubii în interpretarea lor): BITMAPFILEHEADER, BITMAPINFOHEADER, opțional paleta de culori și în final datele imaginii. Variantele formatului BMP apar distincte în domeniile bitmap info header și în cel al paletei de culori.

Intrările în tabela ce reprezintă paleta de culori, în cazul versiunii vechi, sunt constituite din trei octeți care indică componentele de roșu, verde și albastru. În cadrul versiunilor noi ale formatului BMP se adaugă un al patrulea octet și ca urmare, o intrare în cadrul paletei de culori se poate citi ca și un longinteger. În cazul în care ne referim la liniile ce reprezintă imaginea, pe lângă faptul că ele sunt înregistrate începând cu linia de jos, există un al doilea aspect care privește faptul că aceste linii sunt umplute cu octeți poziționați pe zero astfel încât să ocupe un număr par de cuvinte duble. Dându-se o imagine de lățime w (în pixeli) și de adâncime d, numărul octeților de pe o linie este calculat folosind formula octeți/rând = ((w*d+31)/32)*4.

În toate cazurile formatul este compus dintr-un antet care conține informații generale despre imagine (dimensiuni, modul de codificare al culorii, etc.) și o secțiune în care se codifică propriu-zis imaginea. În anumite cazuri, între aceste două secțiuni se inserează o "tabelă de culori".

Antetul ocupă 54 de octeți și are urmatoarea structură:

word Type; /* tipul fișierului "BM" */

dword Size; /* dimensiunea fișierului (în octeți) */

word Res1; /* rezervat (=0) */

word Res2; /* rezervat (=0) */

dword Offset; /* adresa relativă în fișier a codificării imaginii */

dword Length; /* număr de octeți până la sfârșitul antetului (40) */

dword Width; /* lațimea imaginii în pixeli */

dword Heigth; /* înălțimea imaginii în pixeli */

word Planes; /* nespecificat (=1) */

word Color; /* numar de biți/pixel (culoare) */

dword Comp; /* tip compresie (este 0=necomprimat) */

dword Size; /* numărul de octeți din codificarea imaginii */

dword XDef; /* definiție pe orizontală în pixeli/metru */

dword YDef; /* definiție pe verticală în pixeli/metru */

dword ClrUsed;/* numărul de culori utilizate în imagine */

dword ClrImp; /* numărul de culori importante */

3.2 Componentele structurii BMP

În general vorbind, câmpurile nefolosite sau care nu sunt importante pot fi setate pe zero în toate situațiile. În cadrul enumerării următoare am respectat denumirile câmpurilor așa cum apar ele în documentația originală. În primul rând voi prezenta câmpurile structurii pe care am denumit-o BITMAPFILEHEADER:

bfType este un câmp folosit pentru validarea fișierului în ceea ce privește faptul că este o imagine BMP și ocupă 2 octeți. Pentru un fișier BMP imagine acest câmp conține totdeauna valoarea „BM" provenind de la prescuratarea „BitMap". Windows nu suportă alte valori pentru acest câmp pe când OS/2 permite existența a șase valori. Aceste șase valori indică practic ce informații contine fișierul: icon color, icon mono, pointer mouse color și așa mai departe.

bfSize indică mărimea fișierului și are rezervat un spațiu de patru octeți. În cadrul unor instanțe mai vechi ale formatului BMP, acest câmp indică valoarea zero respectiv atunci când este setat poate indica lungimea fișierului în octeți sau în cuvinte (acest lucru depinde de programul care a scris informațiile în fișier). Astfel stând lucrurile, nu trebuie să ne bazăm niciodată pe valoarea indicată în acest câmp. Interpretarea corectă ar fi lungimea fișierului în octeți.

bfReserved1, bfReserved2 sunt două câmpuri rezervate, ocupând fiecare câte doi octeți.

bfOffBits indică offsetul, în octeți, de la începutul fișierului la începutul bitmap-ului. Valoarea stocată în acest câmp este foarte importantă deoarece pe lângă utilitatea evidențiată mai înainte apare și posibilitatea calculului numărului de intrări în cadrul paletei cu ajutorul formulei: numărculori = (OffBits – file_hdr_size – bitmap_hdr_size) / rgb_size.

În continuare am dat descrierea câmpurilor ce apar ca și componente ale structurii denumite BITMAPINFOHEADER:

biSize ocupă patru octeți și indică mărimea header-ului în octeți. Această valoare mai este utilizată pentru a determina ce versiune de format avem în față. Există câteva valori consacrate în ceea ce privește semnificația lor. Astfel dacă valoarea câmpului în discuție este 12 atunci avem de-a face cu versiunea de format mai veche (versiunile vechi sub Windows si OS/2 sunt identice). În cazul în care valoarea câmpului este 40 atunci înseamnă că este vorba despre noul format pentru Windows. Dacă valoarea este 64 atunci este vorba despre noua versiune sub OS/2. Acum mai apare o problemă în cazul în care avem o valoare cuprinsă în intervalul 12 – 64. De obicei putem spune că avem de-a face cu o versiune nouă de format BMP dar nu este o afirmație adevărată în orice context.

Multe aplicații verifică dacă valoarea în discuție este 40, în caz contrar apare un mesaj de

eroare care ne spune că fișierul nu este de tip BMP. După cum se poate observa această strategie de lucru nu este dintre cele mai corecte.

biWidth ocupă patru octeți și reprezintă lățimea imaginii în pixeli. Această valoare nu reflectă și cazul în care este necesară „umplerea liniilor" pentru ca spațiul ocupat să fie multiplu de 32.

biHeight ocupă patru octeți și se referă la înălțimea imaginii în pixeli.

biPlanes ocupă doi octeți și indică numărul de plane de culoare din fișierul bitmap. Câmpul este setat de obicei pe 1.

biBitCount ocupă doi octeți și reprezintă numărul de biți folosiți pentru stocarea informației despre un pixel (se mai numește și adâncime). Valorile corecte pentru acest câmp sunt 1, 4, 8 și 24.

biCompression este o valoare, stocată pe patru octeți, ce indică tipul compresiei folosite în cadrul fișierului respectiv. Valoarea zero indică de fapt că nu avem de-a face cu vreo compresie și pare să fie cam singura valoare care apare aici.

biSizeImage este mărimea în octeți a bitmap-ului (ocupă patru octeți). Unele aplicații se bazează pe o valoare corectă în acest câmp.

biXPelsPerMeter ocupă patru octeți și se referă la mărimea pe orizontală a fișierului în pixeli pe metru.

biYPelsPerMeter ocupă patru octeți și se referă la mărimea fișierului pe verticală în pixeli pe metru.

Parametrii XDef și YDef se referă la dimensiunea fizică a unui pixel (orizontală și verticală). Astfel, dacă acești parametrii au valoarea 2000 înseamnă că un pixel are dimensiunea de 0.5×0.5mm. Acest lucru este valabil numai în cazul prezentării imaginii pe medii care permit impunerea unei anumite dimensiuni pentru pixeli (cazul tipăririi imaginii) și nu în cazul afișării pe ecran.

biClrUsed ocupă patru octeți și indică modul de reprezentare al culorii care poate fi 1, 4, 8 sau 24. Acest număr indică pe câți biți este codificată culoarea la nivelul fiecărui pixel. În cazul utilizării a 24 de biți/pixel nu este necesară utilizarea unei tabele de culori, fiecare pixel fiind codificat printr-o structură de trei octeți:

byte Blue; /* intensitatea componentei albastre */

byte Green; /* intensitatea componentei verzi */

byte Red; /* intensitatea componentei roșii */

În celelalte cazuri se utilizează o tabelă de culori care este utilă pentru a asocia o culoare fiecărui cod de 1, 4 sau 8 biți folosit pentru reprezentarea culorii. Astfel, în cazul utilizării a 8 biți/pixel rezultă că avem la dispoziție 256 de coduri, deci culori diferite. Pentru a indica ce culoare corespunde ficărui cod se utilizează o tabelă cu 256 de elemente cu urmatoarea stuctură:

byte Blue; /* intensitatea componentei albastre */

byte Green; /* intensitatea componentei verzi */

byte Red; /* intensitatea componentei roșii */

byte Res; /* rezervat (=0) */

Codul de 1, 4 sau 8 biți reprezintă indexul în această tabelă de unde se citește culoarea reală a acelui pixel.

biClrImportant ocupă patru octeți și indică numărul culorilor importante folosite.

În cazul în care imaginile utilizează 4 sau 8 octeți pe pixel trebuie să avem o paletă de culori. Numărul valid de culori cuprinse în această paletă variază după cum urmează: 16 și respectiv 256 dar până la urmă ele pot fi mai mici dacă imaginea nu face uz de toate culorile posibile. În cazul în care se folosesc 24 de biți pe pixel avem de-a face cu o imagine full-color care nu mai necesită o paletă de culori.

Ultima secțiune este cea care conține codificarea propriu-zisă a imaginii. Această secțiune conține codurile care corespund culorilor fiecarui pixel dacă imaginea este parcursă linie cu linie de la ultima (cea mai de jos) către prima (cea mai de sus), fiecare linie fiind parcursă de la stânga la dreapta.

Codurile sunt împachetate la nivel de octet (de exemplu dacă se utilizeaza 1 bit/pixel fiecare octet va conține 8 pixeli). Codificarea unei linii trebuie să conțină un număr de octeți multiplu de 2 în cazul utilizării codificării de 1 bit/pixel sau multiplu de 4 în celelalte cazuri, acest lucru realizându-se prin completarea liniei cu un număr corespunzator de octeți suplimentari egali cu 0.

3.3 Compresia BMP

Pixelii dintr-o imagine de tip bitmap sunt comprimați folosind o combinație a trei moduri de lucru.

În modul RLE (run length encoded) „unitatea de compresie" este de 2 octeți și reprezintă de la 1 la 255 de pixeli, toți de aceeași culoare. În secvența 04 07, de exemplu, am spus că urmează patru pixeli având culoarea 07.

În modul escape, primul octet este 0 iar următorii octeți semnifică una dintre următoarele trei posibilități: 0 reprezintă sfârșitul unei linii de imagine, 1 reprezintă sfârșitul fișierului bitmap, 2 indică o comandă deltă. O comandă delta mai este urmată de încă doi octeți care reprezintă deplasarea pe orizontală și pe verticală privind locul unde va apare următorul pixel, în raport cu pixelul curent. De exemplu, o comandă delta arată cam așa: 00 02 05 08. Interpretarea ei este că următorul pixel va fi afișat cu 8 poziții mai jos și cu 5 poziții spre dreapta față de poziția curentă.

Cea de-a treia modalitate este referită prin absolute mode. Prin acest mod primul octet are valoarea zero iar următorul octet are o valoare de 3 sau mai mare reprezentând numărul de pixeli necomprimați care urmează. Un exemplu de folosire a modului absolut este 00 03 09 08 06 care interpretat în mod adecvat ne spune că urmează trei pixeli având valorile 09, 08 și 06. După cum se poate observa, în modul de lucru numit absolut trebuie să avem cel puțin trei pixeli de valori diferite altfel (dacă avem doi pixeli de valori diferite) trebuie să folosim modul de lucru RLE. Considerând că valorile a doi pixeli adiacenți sunt 09 și 07 va trebui să scriem în fișierul de ieșire secvența 01 09 01 07 (ceea ce înseamnă o valoare 09 și apoi o valoare 07). Din această descriere rezultă că fișierele ce urmează a fi comprimate și nu au secvențe repetitive vor ajunge să crească în mărime.

Un fișier ce conține informații despre un icon, sub Windows, se poate recunoaște prin faptul că are o lungime de 32 de biți, folosește patru biți pe pixel și descrie un bloc de 32 x 32 pixeli.

=== Capitolul IV ===

CAPITOLUL IV

ASCUNDEREA UNOR INFORMAȚII ÎN IMAGINI

În acest capitol s-a încercat realizarea unui atac steganografic prin ascunderea unui text și a unui fișier de tip .txt într-o imagine BMP, considerată imagine original, în planul cel mai puțin semnificativ astfel încât existența acestui text să nu poată fi detectată. Limbajul de programare folosit pentru implementare este DELPHI 6.

Am folosit următoarele funcții deja implementate în DELPHI 6(atât pentru partea de ascundere cât și pentru cea de marcare):

function StrToInt (s:string):integer – transformă un șir de caractere(string) într-un număr întreg ;

length( ) – determină lungimea unui șir de caractere;

char( ) – află caracterul știindu-i codul ascii;

function IntToStr (s:integer):string – transformă un număr întreg într-un șir de caractere;

size := FileSize(f) – calculează dimensiunea unui fișier în octeti;

Seek(f,28) – se duce în fișierul f pe poziția 28 (al 28-lea octet);

read(f,c); – citește din fișierul f al 28-lea octet și pune valoarea lui într-o variabilă c (c:=byte;);

write(f,d); – pune în fișierul f pe poziția 28 valoarea d (d:=byte;);

CloseFile(f) – închide un fișier f;

CopyFileTo(a,b) – copie fișierul din locația a în locația b;

div – află restul împărțirii a două numere : 4div2 =0;

mod – află câtul împărțirii a două numere: 4div2 =2;

Am implementat următoarele funcții:

function putere(baza,put:integer):longint; – calculează un număr ridicat la o putere și este folosită când se citesc cei mai puțini semnificativi biți din fiecare octet pentru a se afla textul ascuns;

function BinarToString(binar:string):string; – această funcție este folosită la aflarea textului ascuns în fișier transformând un binar în caracterul respectiv folosindu-se și de funcția putere de mai sus. De exemplu:BinarToString(‘01000010’):=B;

function CharToBinar(car:integer):string; – această funcție transformă un caracter în binar. De exemplu: CharToBinar(35):=00010011;

function StringToBinar(s:String):string; – această funcție transformă un șir de caractere într-un șir de biți de 0 și 1 folosindu-se de funcția de mai sus. Este necesară când se transformă textul/fișierul introdus de noi într-un șir de biți de 0 și 1 pentru a putea fi introdus textul în cel mai puțin semnificativ bit al fiecărui octet. De exemplu: StringToBinar(‘11’) := 0011000100110001;

4.1 Algoritmul de ascundere a unor informații în spatele unor imagini

pentru imaginea original se realizează următoarele:

– se alege imaginea original din lista de fișiere BMP;

– se declară imaginea ca un șir de octeți;

f: file of Byte;

– se citește octetul 28 din header-ul fișierului;

Seek(f,28);

read(f,c);

dacă se găsește valoarea 24 se vizualizează imaginea original, aleasă din lista de fișiere BMP cu ajutorul funcției AssignFile(var f; FileName: string); dacă se găsește o altă valoare (1, 4 sau 8) atunci se genereaza o eroare :

if (c<>24) then begin MessageBox(0,'Imaginea trebuie salvata pe 24 biti', 'Eroare', MB_ICONERROR or MB_OK);

– se calculează dimensiunea fișierului în octeți cu ajutorul funcției :

size := FileSize(f)

și este dată de numărul de pixeli pe orizontală înmulțit cu numărul de pixeli pe verticală și înmulțit cu 3 (numarul de octeți ai fiecarui pixel);

– se calculează numărul maxim de caractere n care poate fi scris în header în octeții 6,7,8 și 9 care sunt octeți nefolosiți puși în 0 logic de obicei și aplicând formula: n:=n1*putere(255,3)+n2*putere(255,2)+n3*putere(255,1)+n4; unde n1, n2, n3 și n4 sunt valorile care se pot scrie în octeții 6,7,8 respectiv 9, iar putere este o funcție definită în program care calculază un număr ridicat la o putere;

– numărul maxim de caractere care poate fi ascuns într-o imagine depinde de

mărimea fișierului în care ascundem și este dat de (size-54)/8;

CaractereDeAscuns:=(size-54)div 8;

– se introduce textul sau se alege fișierul de tip txt din lista de fișiere txt, care se dorește a fi ascuns în ultimul plan ;

dim:=length(textdeascuns) div 8;//length returnează lungimea textului de ascuns în biți

Seek(f,6);

if (dim div putere(255,3)>0) then begin

c:=dim div putere(255,3);

Write(f,c);

dim:=dim mod putere(255,3);

end else Write(f,zero);

Seek(f,7);

if (dim div putere(255,2)>0) then begin

c:=dim div putere(255,2);

Write(f,c);

dim:=dim mod putere(255,2);

end else Write(f,zero);

Seek(f,8);

if (dim div putere(255,1)>0) then begin

c:=dim div 255;

Write(f,c);

dim:=dim mod 255;

end else Write(f,zero);

Seek(f,9);

Write(f,dim);

– dacă se introduce text de la tastatură atunci programul ascunde mai întâi caracterele *$& pentru a putea face deosebirea între text ascuns și fișier atunci când se verifică dacă imaginea conține ceva ascuns;

textdeascuns:=StringToBinar('*$&'+memo1.Text);

– se apelează funcția StringToBinar (‘caracterele introduse de noi’) care întoarce codul ascii al caracterului în binar, după care se ia fiecare bit din șirul obținut și se compară cu fiecare al 8-lea bit din octeții imaginii originale, dacă bitul din șirul de înlocuit este 1/0 iar bitul cel mai puțin semnificativ din octetul în care trebuie să inlocuim este 0/1 atunci se face o operație logica un SAU exclusiv cu 1 scris ca octet iar dacă biții coincid ca valoare atunci bitul nu se modifică;

mask:=1;//00000001

if (textdeascuns[i]='0')and(c mod 2 <>0) then c:=c xor mask;

if (textdeascuns[i]='1')and(c mod 2 <>1) then c:=c xor mask;

– se creează o nouă imagine ce conține și textul/fișierul de ascuns în planul cel mai puțin semnificativ, pixelii din imaginea finală fiind alcătuiți astfel: biții 1 … 7 sunt biții 1 … 7 din imaginea original, iar bitul 8 conține textul ascuns;

– se memorează imaginea "prelucrată" într-un fișier BMP;

SavePictureDialog4.Execute;

if (SavePictureDialog4.FileName<>'') then begin

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog4.FileName);

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

AssignFile(f, SavePictureDialog4.FileName);

pentru imaginea care conține textul ascuns se realizează următoarele:

– se alege imaginea din lista de fișiere BMP;

– se citește dimensiunea textului/fișierului ascuns din octeții 6,7,8 și 9;

numarul de caractere=n=n1*putere(255,3)+n2*putere(255,2)+n3*putere(255,1)+n4;

– se memorează cel mai puțin semnificativ bit din fiecare octet începând cu al 54 și până la al 54+numărul de caractere*8 cu ajutorul funcției:

for i:=1 to n*8 do begin

Seek(f,53+i);//ne ducem pe poziția 53+i în fișier

read(f,d);//citim d

cod:=cod+IntToStr(d mod 2);//conține cel mai puțin semnificativ bit din fiecare octet;

– pentru fiecare caracter e nevoie de 8 octeți adică 2 pixeli și 2 octeți(fiecare pixel având 3 octeți);

– se apelează funcția BinarToString (transformă un șir de octeți în caractere)

textS:=BinarToString(cod);//returnează caracterele introduse de noi

se verifică primele 3 caractere găsite , dacă sunt *$& atunci :

form1.Label4.Caption:='Imaginea contine ascuns textul: ';

dacă nu :

if ((textS[1]<>'*') and (textS[2]<>'$') and (textS[3]<>'&')) then begin

form1.Label7.Caption:='Imaginea contine ascuns fișier ul: ';

– se afișează textul ascuns:

form1.Memo2.text:=textS;

– dacă vrem ca la vizualizare să nu ne mai apară mesajul 'Imaginea conține ascuns fișierul: ' sau 'Imaginea conține ascuns textul: ' ne ducem în header-ul imaginii și punem octeții 6,7,8 și 9 în 0 logic;

c:=0;

Seek(f,6);

Write(f,c);

Seek(f,7);

Write(f,c);

Seek(f,8);

Write(f,c);

Seek(f,9);

Write(f,c);

se memorează imaginea într-un fișier BMP;

SavePictureDialog2.Execute;

if (SavePictureDialog2.FileName<>'') then begin

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog2.FileName);

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

AssignFile(f, form1.SavePictureDialog2.FileName);

se închid toate imaginile;

CloseFile(f);

4.2 Rezultatele obținute în urma rulării algoritmului

IMAGINEA ORIGINALĂ

TEXTUL CARE SE ASCUNDE:

Pentru imaginea original se realizează următoarele:

– se alege imaginea original din lista de fișiere BMP;

– se citește imaginea dintr-un fișier grafic;

– se vizualizează imaginea original, aleasă din lista de fișiere BMP;

– se calculează size care este dimensiunea fișier ului în octeti si este data de numarul de pixeli pe orizontala inmultit cu numarul de pixeli pe verticala si inmultit cu 3 (numarul de octeti ai fiecarui pixel);

– se calculează numarul de caractere care poate fi ascuns in functie de marimea fișier ului in care ascundem si este dat de (size-54)/8;

– se introduce textul care se dorește a fi ascuns în ultimul plan;

– se declară un vector ce conține codurile ASCII ale caracterelor din textul de ascuns;

– se transformă codurile ASCII ale caracterelor în coduri binare;

– se creează o nouă imagine ce conține și textul de ascuns în planul cel mai puțin semnificativ, pixelii din imaginea finală fiind alcătuiți astfel: biții 1 … 7 sunt biții 1 … 7 din imaginea original, iar bitul 8 conține textul ascuns;

– se memorează imaginea "prelucrată" într-un fișier BMP;

IMAGINE CARE CONȚINE TEXTUL DE MAI SUS ASCUNS(stânga)

IMAGINE OBȚINUTĂ DUPĂ ȘTERGEREA TEXTULUI DE MAI SUS(dreapta)

IMAGINEA ORIGINALĂ

IMAGINE CARE CONȚINE 20 590 DE CARACTERE

(ABCDEFGHOJKLMNOPSTUKSJBDLSUGPWDGPUGDSBDLUSGDSUIDGOLSU) SCRISE DE MAI MULTE ORI (stânga) /IMAGINE OBȚINUTĂ DUPĂ ȘTERGEREA CARACTERELOR(dreapta)

IMAGINI OBȚINUTE ÎN URMA ASCUNDERII (stânga)/ ȘTERGERII(dreapta)UNUI FIȘIER (readme.txt)

4.3 Algoritmul de transformare a unei imagini RGB în nuanțe de gri

pentru imaginea original se realizează următoarele:

– se alege imaginea original din lista de fișiere BMP;

– se declară imaginea ca un șir de octeți;

f: file of Byte;

– se citește octetul 28 din header-ul fișierului;

Seek(f,28); read(f,c);

dacă se găsește valoarea 24 se vizualizează imaginea original, aleasă din lista de fișiere BMP cu ajutorul funcției AssignFile(var f; FileName: string); dacă se găsește o altă valoare (1, 4 sau 8) atunci se genereaza o eroare :

if (c<>24) then begin MessageBox(0,'Imaginea trebuie salvata pe 24 biti', 'Eroare', MB_ICONERROR or MB_OK);

– cât timp nu se ajunge la sfârșitul fișierului se fac urmatorele:

while (not(eof(x1))) do begin

if ((j>=54)and ((j-54) mod 3 =0)) then begin//se sare peste header-ul imaginii;

seek(x1,j);//se duce pe prima poziție după header;

read(x1,c1);//se citește octetul respectiv;

seek(x1,j+1);//se duce la al doilea octet;

read(x1,c2);//se citește și cel de-al doilea;

seek(x1,j+2);//se duce la cel de-al treilea octet;

read(x1,c3);//se citește și acesta;

c:=round((c1+c2+c3)/3);//se face media celor 3 octeți citiți și se rotunjește valoarea acestuia la un intreg;

seek(x1,j);//se duce apoi din nou la primul octet de după header;

write(x1,c);// se înlocuiește octetul cu valoarea medie obținută mai inainte;

seek(x1,j+1);//la fel și pentru următorii doi ;

write(x1,c);

seek(x1,j+2);

write(x1,c);

end;

inc(j);//se incrementează j și se fac aceleași calcule pentru grupe de câte trei octeți(adică pentru fiecare pixel);

end;

4.4 Rezultatele obținute :

IMAGINEA ORIGINALĂ IMAGINEA ALB NEGRU

=== Capitolul V ===

CAPITOLUL V

MARCAREA VIZIBILĂ ȘI DEMARCAREA UNOR IMAGINI

5.1 Algoritmul de marcare vizibilă a unor imagini

În acest capitol s-a încercat marcarea vizibilă a unor imagini și demarcarea imaginilor în scopul obținerii pozei originale știindu-se marca folosită la marcare. În acest scop s-a realizat un program (funcțiile utilizate la realizarea programului sunt descrise în capitolul IV) care este descris de un algoritm ai cărui pași sunt prezentați în continuare:

pentru imaginea care vrem să o marcăm se realizează următoarele:

– se alege imaginea original din lista de fișiere BMP;

– se citește imaginea dintr-un fișier grafic;

AssignFile(x1, form1.OpenPictureDialog1.FileName);

Reset(x1);

– se vizualizează imaginea original, aleasă din lista de fișiere BMP;

Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);

– se calculează size care este dimensiunea fișierului în octeți și este dată de numărul de pixeli pe orizontală înmulțit cu numărul de pixeli pe verticală și înmulțit cu 3 (numărul de octeți ai fiecărui pixel);

pentru imaginea considerată marcă se realizează următoarele:

– se alege imaginea considerată marcă din lista de fișiere BMP(trebuie să fie o imagine alb negru);

– se citește imaginea dintr-un fișier grafic;

AssignFile(x2, form1.OpenPictureDialog3.FileName);

Reset(x2);

– se vizualizează imaginea aleasă din lista de fișiere BMP;

Image2.Picture.LoadFromFile(OpenPictureDialog3.FileName);

– se calculează size care este dimensiunea fișierului în octeți și este dată de numărul de pixeli pe orizontală înmulțit cu numărul de pixeli pe verticală și înmulțit cu 3 (numărul de octeți ai fiecărui pixel), atât numărul de pixeli pe orizontală cât și cel pe verticală nu trebuie să fie mai mare decat cel din poza originală în caz contrar se generează o eroare;

if ((image1.Picture.Height<image2.Picture.Height) or (image1.Picture.Width<image2.Picture.Width)) then begin

MessageBox(0, 'Imaginile nu sunt compatibile', 'Eroare', MB_ICONERROR or MB_OK);

pentru a marca vizibil imaginea se realizează următoarele:

– considerăm că am deschis atât imaginea originală cât și marca;

atâta timp cât nu se ajunge la sfârșitul mărcii se caută în imaginea considerată marcă pozițiile corespunzătoare octeților de valoare 0 logic și se duce pe aceeași poziție și în poza originală;

while (not(eof(x2))) //cât timp nu s-a ajuns la sfârșitul fișierului;

do begin read(x2,c2);//citim din marcă pe c2;

if ((j>=54) and (c2=0)) then begin//se sare peste header și se caută în marcă octeții de valoare 0

seek(x1,53+image1.Picture.Width*((j-53-1) div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));// formulă cu ajutorul căreia se află poziția corespunzătoare din imaginea originală unde trebuie să modificăm octetul;

read(x1,v123);//citim în imaginea originală valoarea octetului respective;

vInt:=v123;//inițializăm pe vInt cu valoarea octetului;

– schimbăm valoarea octetului respectiv, noua valoare fiind (vechea valoare+20);

– dacă noua valoare depășește 255(11111111) atunci noua valoare va fi chiar 255.

if (vInt+20>255) then begin // punem condiția dacă vInt+20 depășește 255;

v123:=255;//atunci el ia chiar valoarea 255;

end else v123:=v123+20;//altfel noua valoare va fi vechea valoare +20;

seek(x1,53+image1.Picture.Width*((j-53-1)div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));//ne ducem pe poziția corespunzatoare;

write(x1,v123);// modificăm octetul cu noua valoare;

end;

inc(j);// îl incrementăm pe j pentru a putea verifica toate pozițiile corespunzătoare octeților de valoare 0;

se memorează imaginea "prelucrată" într-un fișier BMP;

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog5.FileName); MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

se închid fișierele deschise;

closefile(x1); closefile(x2);

5.2. Algoritmul pentru marcarea vizibilă fixă a unor imagini

– considerăm că am deschis atât imaginea originală cât și marca;

atâta timp cât nu se ajunge la sfârșitul mărcii se caută în imaginea considerată marcă pozițiile corespunzătoare octeților de valoare 0 logic și se duce pe aceeași poziție și în poza originală;

while (not(eof(x2))) //cât timp nu s-a ajuns la sfârșitul fișierului;

do begin read(x2,c2);//citim din marcă pe c2;

if ((j>=54) and (c2=0)) then begin//se sare peste header și se caută în marcă octeții de valoare 0

seek(x1,53+image1.Picture.Width*((j-53-1) div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));// formulă cu ajutorul căreia se afla poziția corespunzătoare din imaginea originală unde trebuie să modificam octetul;

read(x1,v123);//citim în imaginea originală valoarea octetului respectiv

vInt:=v123;//inițializăm pe vInt cu valoarea octetului ;

– schimbăm valoarea octetului respectiv, noua valoare fiind o valoare arbitrară aleasă de noi in cazul de față v123:= StrToInt(memo3.Text);

seek(x1,53+image1.Picture.Width*((j-53-1)div(image2.Picture.Width*3))*3+((j-53-1) mod (image2.Picture.Width*3)+1));//ne ducem pe poziția corespunzatoare

write(x1,v123);// modificăm octetul cu noua valoare;

end;

inc(j);// îl incrementăm pe j pentru a putea verifica toate pozițiile corespunzătoare octeților de valoare 0;

se memorează imaginea "prelucrată" într-un fișier BMP;

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog5.FileName); MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

se închid fișierele deschise;

closefile(x1); closefile(x2);

Algoritmul de demarcare vizibilă a unor imagini

pentru a demarca imaginea se realizează următoarele:

– considerăm ca am deschis atât imaginea marcată cât și marca;

– se citește imaginea marcată dintr-un fișier BMP;

AssignFile(x1, form1.OpenPictureDialog1.FileName);

Reset(x1);

se citește marca dintr-un fișier BMP;

AssignFile(x2, form1.OpenPictureDialog3.FileName);

Reset(x2);

se caută în imaginea considerată marcă pozițiile corespunzătoare octeților de valoare 0 logic și se duce pe aceeași poziție și în imaginea marcată și se schimbă valoarea octetului respectiv, noua valoare fiind (vechea valoare-20) pană când se ajunge la sfârșitul fișierului;

while (not(eof(x2))) do begin

read(x2,c2);

if((j>=54) and (c2=0)) then begin

seek(x1,53+image1.Picture.Width*((j-53 -1)div(image2.Picture.Width*3))*3+((j-53-1)mod(image2.Picture.Width*3)+1));

read(x1,v123);

if (v123=255) then begin

v123:=250;

end else v123:=v123-20;

seek(x1,53+image1.Picture.Width*((j-53-1)div(image2.Picture.Width*3))*3+((j-53-1)mod (image2.Picture.Width*3)+1));

write(x1,v123);

end; inc(j); end;

dacă vechea valoare este 255(11111111) atunci noua valoare va fi 250;

se memorează imaginea astfel obținută într-un fișier BMP;

CopyFileTo(form1.OpenPictureDialog1.FileName,SavePictureDialog1.FileName)

MessageBox(0, 'Imaginea a fost salvata', 'Confirmare', MB_ICONinformation or MB_OK);

5.4 Algoritmul de comparare a imaginii originale cu imaginea demarcată

– considerăm că am deschis atât imaginea originala cât și cea demarcată;

AssignFile(x1, form1.OpenPictureDialog1.FileName);//se deschide imaginea originală

AssignFile(x2, form1.OpenPictureDialog3.FileName);//se deschide imaginea demarcată

reset(x1);

reset(x2);

dif:=0;//se inițializează dif cu 0;

antet:=54;//al 54-lea octet;

while (not(eof(x2))) do begin //cât timp nu se ajunge la sfârșitul imaginii demarcate;

seek(x1,antet);//ne ducem în imaginea originală pe poziția antet (=54);

seek(x2,antet);//ne ducem în imaginea demarcată pe poziția antet (=54);

read(x1,c1);//citim octetul 54 din imaginea originală;;

read(x2,c2);//citim octetul 54 din imaginea demarcată;;

if c1<>c2 then begin//comparăm cei 2 octeți între ei;

inc(dif); //îl incrementam pe dif dacă sunt diferiți octeții între ei ;

end;

inc(antet); //și incrementăm și antetul pentru a trece la următorul octet;

end;

closefile(x1); //închidem imaginea originală;

closefile(x2);// închidem imaginea demarcată;

5.5 Rezultatele obținute în urma rulării algoritmilor

MARCARE ȘI DEMARCARE VIZIBILĂ

IMAGINEA ORIGINALĂ IMAGINEA CONSIDERATA MARCĂ

IMAGINEA MARCATĂ

IMAGINEA DEMARCATĂ

Rezultatul comparării celor doua imagini: imaginea originală și imaginea demarcată.

O ALTĂ IMAGINE ORIGINALĂ O ALTĂ MARCĂ

IMAGINEA MARCATĂ

IMAGINEA DEMARCATĂ

Rezultatul comparării celor doua imagini: imaginea originală și imaginea demarcată.

O ALTĂ IMAGINE ORIGINALĂ ALTĂ MARCĂ

IMAGINEA MARCATĂ IMAGINEA DEMARCATĂ

Rezultatul comparării celor doua imagini: imaginea originală și imaginea demarcată.

MARCARE VIZIBILĂ FIXĂ

IMAGINEA ORIGINALĂ IMAGINEA CONSIDERATĂ MARCĂ

IMAGINEA MARCATĂ FIX

=== Capitolul VI ===

CAPITOLUL VI

FIABILITATE SOFTWARE

Fiabilitatea este privită ca măsura încrederii pe care o avem în concepția și în capacitatea unui program de a funcționa corect în toate condițiile avute în vedere de la început. Această definiție se referă mai mult la fiabilitatea procesului decât la cea a programului, fiind legată de probabilitatea ca o eroare din program să fie activată de un set specific de intrări. Fiabilitatea produselor software este caracteristica ce exprimă poate cel mai bine particularitățile acestei industrii, dacă abordăm problema în comparație cu fiabilitatea produselor hardware. Există abordări cantitative ale fiabilității, exprimate prin probabilitatea ca un produs software să-și îndeplinească funcțiunile cu anumite performanțe și fără erori într-un interval de timp și în condiții de exploatare date, precum și abordări calitative ce privesc fiabilitatea ca o capacitate a produsului software. Standardul ISO/IEC 9126 [ISO1], definește fiabilitatea ca un set de atribute care se bazează pe capabilitatea produsului software de a-și menține nivelul de performanță în condiții și pe o perioadă de timp stabilite. Limitele fiabilității unui produs software se datorează erorilor din etapele de formulare a cerințelor, proiectare și implementare. Căderile datorate acestor erori depind de modul și condițiile în care este utilizat produsul. Corespunzător ciclului de viață al produsului software, putem distinge o fiabilitate previzională sau proiectată, o fiabilitate experimentală și o fiabilitate operațională (la beneficiar).

Fiabilitatea este aptitudinea produsului software de a funcționa în condiții anormale, în conformitate cu specificațiile sale de proiectare( definiție dată de Mayer). De exemplu, rezistența la introducerea de date incorecte, reluări posibile în caz de pană a sistemului( software sau hardware), posibilitățile de a lucra când totuși sistemul este degradat, etc. Acest factor nu este independent de contextul tehnic în care se utilizează aplicația software.

Problema determinării, asigurării și evaluării calității este o problemă destul de veche; ea a fost abordată de mult timp ceea ce a facut ca, înca de la sfârșitul anilor '80, I.S.O. să publice primele standarde referitoare la calitate. Conform standardului ISO-8402, calitatea este ansamblul caracteristicilor unei entități, care îi conferă aptitudinea de a satisface nevoile exprimate sau implicite . Aceasta se exprimă printr-un sistem de caracteristici, nu este de sine stătătoare și se definește în relația cu terții – clienți, producători, furnizori, sau comercianți. Este o variabilă continuă și presupune satisfacerea atât a nevoilor exprimate, cât și a celor implicite. Conceptul de calitate este tratat, în prezent, ca un concept dinamic, ce leagă calitatea produsului sau a serviciului de alte două elemente fundamentale: calitatea proiectului și calitatea fabricației.

Asigurarea calitații produsului final se realizează treptat, pe masură ce se avansează în procesul de obținere a acestuia. Calitatea sistemelor de programe se creează în procesul de realizare și se manifestă în procesul de utilizare a acestora. În industria de software, o importanță deosebită o are relația de dependență dintre specificul și calitatea procesului generator, calitatea proiectului și calitatea produsului.

Conform ISO 8402, calitatea este prezentă în fapt printr-un set de caracteristici ce pot fi împărțite în:

– caracteristici economice: se exprimă prin intermediul costurilor, al economiilor de resurse, precum și prin creșterile de randament și de productivitate;

– caracteristici sociale si psiho-senzoriale: se manifestă prin punerea în valoare a elementelor creatoare, prin eliminarea rutinei și a stereotipiei precum și prin instruirea asistată a operatorilor;

– caracteristici tehnice si de utilizare: sunt prezentate în literatura de specialitate, iar I.S.O. a elaborat un model care reprezintă esența standardului ISO 9126 .

Între caracteristicile de calitate există o mulțime de relații de subordonare, interdependente, ierarhizare, agregare sau decompoziție, iar complexitatea acestor relații face ca ansamblul caracteristicilor de calitate să alcătuiască un sistem. Caracteristicile de calitate constituie agregări ale unor atribute de calitate, ce sunt corespunzatoare unor proprietăți concrete, pe care trebuie să le posede sistemele de programe.

Managementul calității este componenta funcției generale de conducere, care determină și pune în aplicare politica în domeniul calității și deține responsabilitățile pentru toate activitățile care concură la îndeplinirea obiectivelor privind calitatea. Există patru funcții principale ale managementului calității:

– planificarea calității: cuprinde activitățile prin care se stabilesc obiectivele și cerințele privind calitatea;

– controlul calității: include activitățile de monitorizare a desfășurării proceselor și de evaluare a rezultatelor referitoare la calitate, în raport cu obiectivele stabilite, în scopul eliminării deficiențelor și/sau prevenirii apariției acestora;

– asigurarea calității: cuprinde activitățile preventive prin care se urmărește, în mod sistematic, corectitudinea și eficiența activităților de planificare și control, pentru a garanta obținerea rezultatelor la nivelul calitativ asteptat;

– îmbunătățirea calității: cuprinde activitățile desfășurate în fiecare etapă a ciclului de viață a produsului, în scopul obținerii unui nivel calitativ superior celui planificat, în condițiile desfașurării corespunzătoare a activitaților de planificare, control și asigurare a calității.

6.1 Metode de realizare a software-ului fiabil

Datorită dificultăților întâmpinate la studierea ”a posteriori” a fiabilității software-ului,

s-a impus necesitatea găsirii unor metode de proiectare fiabilă a software-ului. Dintre principiile de bază care trebuie respectate la proiectare se pot aminti:

– proiectul produsului software trebuie să fie corect din punct de vedere logic și compatibil cu specificațiile temei de proiectare;

– din punct de vedere al fiabilității și mentenabilității, el trebuie să aibă o structură modulară, fiecare modul să aibă o dimensiune mică și să comunice cu celelalte printr-un singur punct;

– utilizarea principiilor programării structurate, care asigură o mai mare claritate și logică internă, posibilitatea tipizării proiectării și facilitatea reproiectării și mentenanței produselor software;

– utilizarea tehnicilor orientate pe obiect.

Proiectarea produselor software poate fi realizată utilizând mai multe metode și anume: descendentă( top – down), ascendentă( bottom – up), sau mixtă ( top–down – bottom-up).

O importantă contribuție la realizarea de produse software fiabile o poate aduce utilizarea tehnicilor de programare defensivă. Aceasta presupune includerea în programele proiectate a unor verificări care să permită reducerea substanțială (sau chiar eliminarea) unor posibile erori software. De exemplu, în cazul proiectării unui modul de program, proiectantul trebuie să pornească de la premisa că modulul poate accepta date de intrare incorecte, ceea ce poate conduce la date de ieșire incorecte, dar credibile. Pentru a înlătura acest pericol, conform principiilor programării defensive vor trebui incluse, la începutul modulului de program, verificările corespunzătoare asupra datelor de intrare.

Un sistem tolerant la erori își poate continua execuția corectă a funcțiilor sale de intrare/ieșire chiar în prezența unei mulțimi de erori ce apar în timpul funcționării sale, fără o intervenție din exterior. Prin execuția corectă se va înțelege că programele, datele și rezultatele operării sistemelor nu conțin erori, iar timpul de execuție a unei operații nu depășește o limită specificată.

La proiectarea unui sistem software tolerant la erori trebuie avute în vedere următoarele obiective principale:

– detectarea și localizarea erorilor software;

– limitarea, cât mai mult posibil, a efectului propagării erorilor;

– verificarea integrității sistemului, periodic sau înaintea executării proceselor critice.

În firmele de soft există norme privind munca de programare, și condiții de calitate, care stabilesc media erorilor la mia de linii de cod, numărul mediu de erori care pot fi corectate în etapele de testare, precum și procentul de eventuale erori nedepistate. Gradul de acceptare al acestor erori depinde de destinația sistemului și influențează desigur prețul de vânzare al produsului program, sau a sistemului în ansamblu.

Analiza, depistarea și corectarea erorilor din pachetele de programe, a bug-urilor, este o activitate curentă în orice firmă de soft. În decursul anilor s-au încercat diferite procedee de automatizare a depistării și corectării erorilor, realizarea unor mecanisme de testare a programelor. A rămas celebru un panseu al lui Djikstra care sună cam așa: "Orice program de test poate evidenția cel mult prezența unei erori, niciodată absența erorii".

Redundanța software poate fi implementată la diferite niveluri: sistem, instrucțiune, date. Pot fi evidențiate două metodologii principale pentru restabilirea, în limite acceptabile de timp, a funcționării continue a sistemului software după erori. Chiar și în cazul utilizării redundanței software, este posibil să existe unele erori software ce nu pot fi detectate. De aceea, se impune realizarea de software tolerant la erori prin: redundanța software statică sau redundanța software dinamică.

Redundanța software statică presupune existența mai multor module software (cel puțin 3), care au aceleași funcții și funcționează cvasi – simultan. Pentru minimizarea efectului erorilor software datorate proiectării, este indicat ca modulele să fie realizate în mod independent. Utilizarea redundanței statice prezintă dezavantajul supraîncărcării procesorului hardware. În timpul execuției, cantitatea de resurse necesare( memorie, timp de execuție,etc.) pentru o aplicație crește proporțional cu numărul modulelor redundante.

În cazul redundanței software dinamice, la apariția unei erori în modulul soft principal, acesta este imediat înlocuit cu un modul de rezervă care a fost proiectat să realizeze aceleași funcțiuni.

Scopul redundanței software constă în detectarea defectărilor hardware, corecția erorilor( acolo unde este posibil), și restabilirea funcționării după apariția unei defectări.

6.2.Nivele prescrise de fiabilitate

Încă din faza stabilirii cerințelor și specificațiilor, trebuie să se impună nivelul de fiabilitate al sistemului ca un compromis între prețul de cost și consecințele defectărilor. Astfel, un produs software conceput pentru cercetări spațiale cu participare umană trebuie să aibă o fiabilitate mai mare decât unul pentru jocuri pe calculator. Este necesar deci ca produsele software să se înscrie în anumite clase de fiabilitate. Clasele de fiabilitate sunt următoarele:

Foarte scazută( very low). Acest nivel se prescrie atunci când defectarea are ca singură consecință inconvenientul producătorului de a înlătura o neregulă în program. Asemenea situație intervine, de exemplu în cazul modelelor demonstrative sau al simulărilor.

Scazută (low). Acet nivel corespunde în cazurile în care defectarea implică o pierdere mică, ușor de recuperat pentru beneficiar. Sistemele utilizate în predicție pe termen lung sunt exemple tipice.

Nominală( nominal). Acest nivel corespunde cazului când defectarea implică o pierdere moderată pentru beneficiar, dar remedierea situației nu este prea costisitoare. Sistemul de gestionare a stocurilor sau sistemele informaționale de conducere sunt exemple tipice pentru această clasă de fiabilitate.

Ridicată( high). Efectele defectării pot implica o pierdere financiară mai mare sau un inconvenient major pentru factorul uman. Exemple tipice sunt sistemele bancare și cele ale distribuției energiei electrice.

Foarte ridicată( very high). Efectele defectării pot consta în pierdere de vieți omenești. Cazul tipic îl constituie sistemul de control al reactoarelor nucleare.

În funcție de nivelul de fiabiliate prescris, se poate stabili efortul necesar care trebuie făcut în fiecare etapă a realizării produsului.

Proiectarea structurii

Asigurarea fiabilității la nivelul proiectului se bazează pe realizarea unei structuri cât mai simple și transparente. Pentru a avea control asupra acestor caracteristici trebuie să se cunoască:

P1= numărul total de module din program

P2= numărul de module dependente de intrari( I) sau ieșiri( E)

P3= numărul de module dependente de o procesare anterioară

P4= numărul de elemente din bazele de date

P5= numărul elementelor neunice din baza de date

P6= numărul de segmente din baza de date

P7= numărul de module cu mai mult de o intrare și o ieșire

Cu ajutorul mărimilor P1 – P7 se evaluează șase mărimi derivate D1 – D6 care exprimă simplitatea structurii programului. Cu cât valorile Di sunt mai mari, cu atât este mai îndoielnică fiabilitatea programului.

Metrici software

Metricile software pot fi împărțite în două categorii:

1. Metrici software de producție;

2. Metrici software de proces.

Primele măsoară produsele soft din punct de vedere al producerii lor, cum ar fi codul sursă sau documentele de proiectare.

Cele din a doua categorie măsoară procesul de dezvoltare a software-ului, cum ar fi numărul de ore/om necesare în activitățile de dezvoltare, proiectare și codificare ale produsului soft.

Metricile sunt folositoare în condițiile în care sunt implementate într-o secvență bine fundamentată de activități. Pașii de urmat în utilizarea metricilor, sunt:

1 – evaluarea procesului;

2 – determinarea metricilor și a datelor ce trebuie colectate;

3 – determinarea celor mai potrivite tehnici și instrumente pentru a fi

utilizate în cadrul proiectului;

4 – estimarea costului și programului proiectului;

5 – determinarea nivelului metricilor;

6 – construirea unei baze de date a proiectului;

7 – evaluarea costului și a programului proiectului;

8 – evaluarea productivității și a calității;

9 – formarea unei baze pentru estimări viitoare.

Similar Posts