BAB V PENUTUP
5.2 Saran
Berikut adalah saran-saran yang berkaitan dengan penelitian yang telah dilakukan.
1. Perlu dilakukan penelitian lanjutan untuk cira termampat tak berugi lainnya seperti PNG sehingga dapat diketahui perbedaan dalam keandalan penyisipan data.
2. Perlu dilakukan penelitian lanjutan untuk steganografi pada audio maupun video.
DAFTAR PUSTAKA
[1] Achmad, B. dan K. Firdausy, Teknik Pengolahan Citra Digital, Andi Publishing, Yogyakarta, 2005.
[2] Ziv. J. and A. Lempel, "Compression of Individual Sequences via Variable-Rate Coding," IEEE Transactions on Information Theory, vol. 24, no. 5, September, 1978.
[3] Munir, R., Pengolahan Citra Digital dengan Pendekatan algoritmik, Informatika, Bandung, 2004.
[4] Robi’in, B., Pemrograman Grafis Multimedia Menggunakan Delphi, Andi Offset,Yogyakarta , 2004.
[5] Bender, W., D. Gruhl, and N. Morimoto, Techniques for Data Hiding, Massachusetts Institute of Technology, Media Laboratory Cambridge, Massachusetts USA, San Jose CA, February, 1995.
[6] Octaviano, S., Aplikasi Steganografi Menggunakan Metode Pensinyalan
LSB (Least Significant Bit) pada File Gambar dengan Format BMP,
Skripsi S-1, Universitas Diponegoro, Semarang, 2004 .
[7] Linawati dan H. Panggabean, Perbandingan kinerja algoritma kompresi
huffman, LZW, dan DMC pada berbagai tipe file, Integral, vol 9 no 1,
Maret, 2004.
[8] Guillermito, Easily Breaking a very weak Steganography Software, http://www.guillermito2.net/stegano/camouflage.html, 16 September 2002.
[9] Armyta, D., Studi Mengenai Aplikasi Steganografi Camouflage Beserta
Pemecahan Algoritmanya,
http://www.informatika.org/~rinaldi/Kriptografi/2006-2007/makalah1-2006/makalah1-007.pdf, 2006.
[10] Tien, L., Destegging Tutorial, http://www.unfiction.com/dev/tutorial, 2002.
[11] Mangarae, A., Steganography FAQ,
www.infosecwriters.com/text_resources/pdf/Steganography_AMangar ae.pdf, 18 Maret 2006.
[12] Poli, L., Penerapan Steganografi dengan Citra Digital Sebagai File
[13] Zhao, J. and E. Koch, Embedding Robust Labels Into Images For Copyright
Protection, Germany,Vienna, Agustus 1995.
[14] Daryanto, T., Standar-Standar Kompresi Pada Gambar,
www.bl.ac.id/dosen/tri_daryanto/kompresi.PDF, Maret 2004.
[15] Wikipedia, Steganography, http://en.wikipedia.org/wiki/Steganography, 3 Mei 2007.
[16] ---, A Stegography implementation in Delphi,
BIODATA MAHASISWA
Nama : ARIF NUR BUDI SETIYO
NIM : L2F 304 217
Konsentrasi : Elektronika dan Telekomunikasi Tempat/Tgl. Lahir : Semarang / 02 November 1981
Alamat : Jl. Pucang Anom IX No 7.
Pucang Gading. Mranggen No. Telp/HP : 024 70180109 / 0815 7577 5849 Alamat e-mail : Ayip_Jr02@yahoo.com
Ayip@hotmail.com
4yipxxx@Gmail.com
Nama Orang Tua : Bambang Sumaryo
Alamat Orang Tua : Jl. Pucang Anom IX No : 7. Pucang Gading. Mranggen. Demak
No. Telp/HP : 024 76743888 IP Kumulatif : 3,09
Tanggal Lulus : 19 Juni 2007
Masa Studi :
Semarang, 20 Juni 2007
LAMPIRAN
LAMPIRAN
unit fmainform;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Menus, ExtCtrls, StdCtrls, ExtDlgs,GIFIMAGE, IdComponent, IdTCPConnection, IdTCPClient, IdMessageClient, IdSMTP,IdBaseComponent, IdMessage,jpeg; type TDataRek=record id:string[3]; pass:string[10]; namafile:string[15]; size:integer; data:array of byte; end; TMainForm = class(TForm) MainMenu1: TMainMenu; Input1: TMenuItem; Bukafilegambar1: TMenuItem; Bukafiledata1: TMenuItem; N1: TMenuItem; INPUT2: TMenuItem; OUTPUT1: TMenuItem; SimpansebagaiGIF1: TMenuItem; Bantuan1: TMenuItem; entangprogram1: TMenuItem; N2: TMenuItem; Keluarkesistem1: TMenuItem; PageControl1: TPageControl; StatusBar1: TStatusBar;
TabSheet1: TTabSheet; TabSheet2: TTabSheet; GroupBox1: TGroupBox; GroupBox2: TGroupBox; ScrollBox1: TScrollBox; Image1: TImage; GroupBox3: TGroupBox; ScrollBox2: TScrollBox; Image2: TImage; Timer1: TTimer; OpenPictureDialog1: TOpenPictureDialog; SavePictureDialog1: TSavePictureDialog; OpenDialog1: TOpenDialog; INPUTDECODE1: TMenuItem; Bukafile1: TMenuItem; Label4: TLabel; Edit4: TEdit; Label5: TLabel; Edit5: TEdit; Edit6: TEdit; Label6: TLabel; Label7: TLabel; Button2: TButton; Button3: TButton; SaveDialog1: TSaveDialog; Button1: TButton; entanganda1: TMenuItem; PB1: TProgressBar; Label1: TLabel;
procedure Bukafilegambar1Click(Sender: TObject); procedure Bukafiledata1Click(Sender: TObject); procedure SimpansebagaiGIF1Click(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure PageControl1Change(Sender: TObject); procedure Keluarkesistem1Click(Sender: TObject); procedure entangprogram1Click(Sender: TObject); procedure Bukafile1Click(Sender: TObject);
procedure Edit4Change(Sender: TObject); procedure Button3Click(Sender: TObject); procedure entanganda1Click(Sender: TObject); private { Private declarations } public { Public declarations } hasprocess:boolean; adagambar:boolean; mygif:TGIFImage; modedecode:boolean; maxchar:integer; ext:tdatarek; end; var MainForm: TMainForm; implementation
uses faboutform, splash;
{$R *.dfm}
// prosedur untuk mengambil data dari file ke record agar mudah dikonversi ke bits
procedure loaddata(var d:TDataRek;fn:string); var f:file; // tipe f: file (untuk membuka file) begin
assignfile(f,fn); // akses file fn
reset(f,1); // reset file untuk dibaca
setlength(d.data,filesize(f)); // siapkan tempat untuk menampung isi file
blockread(f,d.data[0],filesize(f)); // baca isi file ke tempat penampung
d.namafile:=ExtractFileName(fn); // simpan juga namafile (namanya saja)
d.size:=filesize(f); // simpan ukuran file closefile(f); // tutup file
d.id:='###'; // beri tanda end; function datatobits(x:tdatarek):tbits; var n,i,j:integer; b:^byte; begin
result:=tbits.create; // persiapkan kelas hasil (kelas tbits)
b:=@x; // arahkan pointer b ke data x result.Size:=8*(sizeof(x)-4)+8*(high(x.data)+1); // siapkan jumlah data yang harus dikonversi ke bit
n:=0; // inisialisasi // convert header
for i:=1 to sizeof(x)-4 do begin // untuk i = 1 s/d ukuran header x
for j:=0 to 7 do begin // untuk setiap bit (ibyte=8bit) result.Bits[n]:=(b^ and (1 shl j))>0; // simpan bit inc(n); // majukan n
end;
inc(b); end;
// convert data
for i:=0 to high(x.data) do begin //untuk i= 0 sampai jumlah data dari file yg disisipkan
for j:=0 to 7 do begin // untuk setiap bit (ibyte=8bit) result.Bits[n]:=(x.data[i] and (1 shl j))>0; // simpan bit inc(n); // majukan n
end; end; end;
procedure TMainForm.FormCreate(Sender: TObject); begin
adagambar:=true; // inisialisasi
hasprocess:=false; // tanda bahwa gambar dan data belum diproses
mygif:=TGIFImage.Create; // komponen untuk mengesave file GIF modedecode:=false; // mode sekarang = buka file
maxchar:=image1.Width*image1.Height div 8; // maksimum ukuran data yg disipkan
end;
procedure TMainForm.Bukafilegambar1Click(Sender: TObject); begin
if OpenPictureDialog1.Execute then begin // buka dialog membuka gambar, bila sukses lanjutkan ke blok berikut
button3.Visible:=false; // hilangkan tombol simpan data button2.Visible:=true; // tampilkan tombol proses
modedecode:=false; // mode = menyisipkan
image1.picture.LoadFromFile(openpicturedialog1.FileName); // load gambar dan tampilnkan
maxchar:=image1.Width*image1.Height div 8; // hitung maksimum data yg bisa disisipkan
adagambar:=true; // sudah ada gambar hasprocess:=false; // belum diproses
StatusBar1.SimpleText:='Silahkan ketik atau ambil file data(teks) yang akan disisipkan. Maksimal '+inttostr(maxchar)+' karakter.';
GroupBox1.Caption:=' Gambar (maksimal '+inttostr(maxchar)+' byte dapat disisipkan) ';
end; end;
procedure TMainForm.Bukafiledata1Click(Sender: TObject); var f:file;
begin
if OpenDialog1.execute then begin // buka file dialog untuk membuka data yg akan disisipkan
StatusBar1.SimpleText:='Gambar akan segera diproses setelah anda melihat output.';
hasprocess:=false; // belum proses
edit5.text:=opendialog1.FileName; // tampilkan nama filenya assignfile(f,opendialog1.FileName); // akses ke file itu reset(f,1); // buka untuk dibaca
edit6.text:=inttostr(filesize(f)); // tampilkan ukuran file closefile(f); // tutup file
if strtoint(edit6.text)>maxchar then begin
edit5.text:=''; // kosongkan namafile dan ukurannya edit6.text:='';
Application.MessageBox('Ukuran file lebih besar dari data yg bisa ditampung, jadi file ditolak !','Eror',0)
end;
end else begin
edit5.text:=''; // kosongkan namafile dan ukurannya edit6.text:='';
end; end;
procedure TMainForm.SimpansebagaiGIF1Click(Sender: TObject); begin
if not hasprocess then begin // jika belum diproses keluar Application.MessageBox('Gambar belum diproses !','Kesalahan',0);
exit; // keluar prosedure ini end;
if SavePictureDialog1.execute then // buka dialog untuk menyimpan file GIF
mygif.SaveToFile(savepicturedialog1.filename); // simpan file GIF
end;
procedure TMainForm.Timer1Timer(Sender: TObject); begin
SimpansebagaiGIF1.visible:=adagambar and hasprocess and (not modedecode); // jika gambar output siap, tampilkan tombol simpan Bukafiledata1.Enabled:=(not modedecode); // kalau sedang menyampur menu buka (decode) di non aktifkan
end;
procedure TMainForm.PageControl1Change(Sender: TObject); // Fungsi ini menciptakan palet 128 warna dasar, kembar
// jadi warna ke 0 dan ke 128 adalah sama, 1 dan 129 sama dst.
var
i,r,g,b : integer;
Pal : tMaxLogPalette; begin
Pal.palVersion := $0300; // inisialisasi palet Pal.palNumEntries := 256; // jumlah warna palet i:=0; // mulai dari warna ke 0
for r := 0 to 3 do for g := 0 to 7 do for b := 0 to 3 do begin
// buat data palet dengan warna tertentu with (Pal.palPalEntry[i]) do begin peRed := r*255 div 3; // merah peGreen := g*255 div 7; // hijau peBlue := b*255 div 3; // biru peFlags := PC_NOCOLLAPSE; // end;
// buat data palet dengan warna yg sama dengan diatas tapi untuk nomor warna+128
with (Pal.palPalEntry[i+128]) do begin peRed := r*255 div 3;
peGreen := g*255 div 7; peBlue := b*255 div 3; peFlags := PC_NOCOLLAPSE; end;
inc(i); // increment nomor warna yg akan dibuat paletnya end;
Result := CreatePalette(pLogPalette(@Pal)^); // panggil fungsi buat palet end; var btmpp,btmp:tbitmap; n,y,x:integer; p:^byte; dr:tdatarek; data:tbits; tt:tdatetime;
begin
// jika gambar belum diproses dan mode sekarang adaalh encode tt:=now;
pb1.visible:=true;
if (not modedecode) and adagambar and (not hasprocess) and (edit5.text<>'') then begin
// buat bitmap sesuai gambar input dengan warna palet yang kita buat
btmpp:=tbitmap.create; // inisialisasi btmpp.Width:=image1.Width; // set lebar btmpp.height:=image1.Height; // set tinggi btmpp.PixelFormat:=pf24bit; // set format warna
btmpp.Canvas.Draw(0,0,image1.picture.Graphic); // kopi gambar dari output
btmp:=ReduceColors(btmpp,rmPalette,dmFloydSteinberg,0,mypa let); // proses reduksi warna dengan palet yg kita buat
btmpp.free; // bebaskan data proses // konversi teks input ke bits
loaddata(dr,edit5.text); // ambil data dari file yg akan disisipkan
dr.pass:=edit4.text; // simpan pasword
data:=datatobits(dr); // konversi data ke bits // lakukan penyisipan data ke gambar
n:=0; //
for y:=0 to btmp.Height-1 do begin // loping vertikal p:=btmp.ScanLine[y]; // inisialisasi lokasi data warna untuk baris ke y
for x:=0 to btmp.Width-1 do begin // looping horisintal // untuk setiap pixel di input sisipkan 1 bit data ke bit 7 if (n<data.size) and data.bits[n] then p^:=p^+128; inc(n); // bits berikutnya
inc(p); // picel berikutnya
pb1.Position:=n*100 div (btmp.width*btmp.height); end;
end;
// simpan sebagai coba.gif
btmp.free; // buang data proses // tampilkan gambar hasil
image2.Picture.Assign(mygif); hasprocess:=true; // sudah proses
StatusBar1.SimpleText:='Gambar sudah selesai diproses, bisa disimpan sebagai GIF';
end;
tt:=(now-tt)*(24*60*60);
label1.caption:='Waktu proses :'+format('%5.5f detik',[tt]); pb1.visible:=false;
end;
procedure TMainForm.Keluarkesistem1Click(Sender: TObject); begin
if Application.MessageBox('Benar mau keluar ?','Konfirmasi',MB_YESNO)=id_NO then exit;
close; end;
procedure TMainForm.entangprogram1Click(Sender: TObject); begin
aboutform.showmodal; end;
procedure TMainForm.Bukafile1Click(Sender: TObject); var x,y:integer; p:^byte; b:byte; n:integer; id:string[5]; db:^byte; dn:integer; tt:tdatetime; begin
// mendecode gambar GIF untuk mengambil data yg disisipkan
if OpenPictureDialog1.Execute then begin // buka file open dialog
if pos('.gif',lowercase(openpicturedialog1.FileName))=0 then begin // jika tidak ada kata .gifnya, tolak
application.MessageBox('Hanya file GIF','Informasi',0); exit;
end;
edit5.text:=''; // kosongkan tampilan nama file dan ukurannya edit6.text:='';// inisialisasi
modedecode:=true; // mode = decode
image1.picture.LoadFromFile(openpicturedialog1.FileName); // buka file gambar
image2.picture.Assign(image1.Picture); // tampilkan jug di output
adagambar:=true; // gambar ada hasprocess:=true; // sudah diproses n:=0; // counter untuk bit (1-8) b:=0; // penampung bit (byte) // load file yang akan didecode
mygif.LoadFromFile(openpicturedialog1.FileName); id:=''; //
db:=@ext; // pointer ke lokasi penyimpan bit dn:=0; // jml data yg sukses
for y:=0 to mygif.height-1 do begin p:=mygif.Bitmap.ScanLine[y]; for x:=0 to mygif.Width-1 do begin
// baca tiap-tiap pixel apakah bit ke 7 bernilai 1 if p^>=128 then b:=b+(1 shl n);
inc(p); n:=n+1;
// untuk setiap 8 pixel, gabungkan menjadi 1 karakter ASCII if n=8 then begin // jika udah terkumpul 8 bit
n:=0;
// simpan di teks hanya apabila masih 24 piksel pertama if length(id)<3 then id:=id+chr(b); // simpan bits
if dn<sizeof(tdatarek)-4 then db^:=b; // simpan di header if (dn>=sizeof(tdatarek)-4) and (dn<sizeof(tdatarek)-4+ext.size)
then db^:=b; // simpan di data inc(db); // majukan penyimpan
inc(dn); // majukan sumber
if dn=sizeof(tdatarek)-4 then begin // jika ukuran file sudah diketahui
setlength(ext.data,ext.size); // siapkan penampung data db:=@ext.data[0]; // siapkan pointer ke data
end;
b:=0; // kosongkan b end;
end;
if (length(id)=3) and (id<>#3'##') then break; // jika id tidak sama dengan ### berarti tidak ada sisipannya
end;
// tampilkan hasil
tt:=(now-tt)*(24*60*60);
label1.caption:='Waktu proses :'+format('%5.5f detik',[tt]); if id<>#3'##' then application.MessageBox('Gambar ini tidak mengandung data !','Informasi',0)
else begin
edit4.text:=inputbox('Keamanan','Masukkan kata sandi',''); // tanyakan password
if edit4.text<>ext.pass then application.MessageBox('Kata sandi anda salah !','Informasi',0)
else begin
button2.Visible:=false; // tombol proses disembunyikan button3.Visible:=true; // tombol simpan ditampilkan edit4.Enabled:=false; // edit 4 tidak bisa diedit edit5.text:=ext.namafile; // simpan nama file edit6.text:=inttostr(ext.size); // ukuran file
StatusBar1.SimpleText:='Silahkan simpan data yang tersimpan di gambar ini.';
GroupBox1.Caption:=' Gambar Yang akan didecode '; end;
end; end; end;
procedure TMainForm.Edit4Change(Sender: TObject); begin
hasprocess:=false; // kalau password diganti harus proses ulang
StatusBar1.SimpleText:='Gambar akan segera diproses setelah anda melihat output.';
end;
procedure TMainForm.Button3Click(Sender: TObject); var f:file;
begin
SaveDialog1.FileName:=edit5.text; // nilai awal saat membuka dialog
if savedialog1.Execute then begin // buka dialog
assignfile(f,savedialog1.filename); // buka akses ke file rewrite(f,1); // siapkan untuk ditulisi ulang
blockwrite(f,ext.data[0],ext.size); // tulis data closefile(f); // tutup file
end; end;
procedure TMainForm.entanganda1Click(Sender: TObject); begin
splashform.show; end;