Xây dựng chương trình dựa trên thuật toán LSB

Một phần của tài liệu Đề tài Ứng dụng ẩn mã và giấu tin trong ảnh (Trang 36)

4.1.1. Ảnh BITMAP

Ảnh BITMAP là định dạng ảnh do microsoft đề xuất , có phần mở rộng là BMP , loại ảnh này truyền tải , sử dụng rộng rãi trên máy tính , và các thiết bị điện tử khác. Ảnh bitmap được chia thành ba dạng : ảnh nhị phân ( ảnh đen trăng ) , ảnh đa mức xám , ảnh màu.

- Ảnh đen trắng : là ảnh mà mỗi điểm ảnh chỉ thể hiện một trong hai trạng thái 0 và 1 để biểu diễn trạng thái điểm ảnh đen hay trăng.

- Ảnh đa mức xám : là ảnh mà mỗi điểm ảnh được biểu diễn bởi một giá trị và đó là cường độ sáng của điểm ảnh.

- Ảnh màu : là ảnh mà mỗi điểm ảnh được biểu diễn bởi ba đại lượng R, G, B . Số lượng màu có thể của loại ảnh này lên tới 265^3 màu khác nhau.Nhưng số lượng màu trên thực tế của một ảnh nào đó thường khá nhỏ. Để tiết kiệm bộ nhớ với các ảnh có số lượng màu nhỏ hơn 256 thì màu các điểm ảnh được lưu trữ dưới dạng bảng màu.Với ảnh có số màu lớn thì các điểm ảnh không tổ chức dưới dạng bảng màu , khi đó giá trị của các điẻm ảnh chinh là giá trị của các thành phần màu R,G,B. Với ảnh có số lượng màu lớn ,tùy theo chất lượng ảnh mà quyết định số bit để biểu diễn cho mỗi màu thường là 24 bit, hoặc 32 bit . Với ảnh 24 bit mỗi thành phần màu được biểu diễn bởi một byte(8 bit).

Ảnh bitmap đựợc lưu trữ dưới dạng nhị phân, một tệp dạng bitmap được chia thành các phần cơ bản như :

- Phần tiêu để tệp (Bitmap header)

- Thông tin về ảnh (Bitmap Infor)

- Bảng màu (Palette Table)

- Vùng dữ liệu(Data)

Thứ tự được lưu trữ trong bộ nhớ như sau: Bitmap Header->Bitmap Infor->Palette Table->Data

4.1.2. Ý nghĩa của các phần trong tệp ảnh bitmap

- Bitmap Header: Mô tả thông tin chung về tệp định dạng bitmap, độ lớn của phần này cố định với mọi tệp bitmap.

- Bitmap Infor: Mô tả thông tin về ảnh được lưu trữ, độ lớn của phần này cố định.

- Pallete Table: Bảng màu của ảnh bitmap, độ lớn của phần này có thể bằng không ( không có bảng màu) đối với ảnh đen trắng và ảnh màu có số lượng màu lớn hơn 256 màu.

- Data: Thông tin về từng điểm ảnh , độ lớn của phần này phụ thuộc vào kich thước ảnh. Phần Data lưu trữ ảnh theo hướng từ dưới nên trên và từ trái qua phải.

4.1.3. Kích thước và giá trị các trường trong tệp ảnh

Bitmap Header :Phần này có độ lớn cố định là 14 bytes , phần này dùng để mô tả thông tin chung về tệp như :

Kiểu tệp, độ lớn và một số thông tin liên qua đến tệp.

Offset( byte) Giá trị Ý nghĩa

1 ‘B’ Định dạng kiểu tệp

2 ‘M’ Định dạng kiểu tệp

3 -> 6 Unsigned long Kích thước tệp

7 -> 10 Zero Reserved

11 -> 14 Unsigned long Địa chỉ phần dữ liệu

Hình 4.1: Ý nghĩa từng trường trong vùng Bitmap Header

Trong phần Bitmap Header có mô tả thông tin về độ dài tệp , thông tin này thực sự cần thiết với mọi chương trình .Tuy nhiên qua thực nghiệm thấy rằng với một số tệp thông tin này không chính xác. Do đó trong báo cáo đưa cách tính kích thước tệp bitmap thông qua công thức:

Tệp_Size=Sizeof(Bitmap Header ) + Sizeof(Bitmap Infor) + Sizeof(Pallete) + Sizeof(Data)

Địa chỉ vị (offset) của vùng dữ liệu có thể được xác định thông qua công thức :

Đối với ảnh đen trắng và ảnh màu có số lượng màu lớn hơn 256 thì giá trị địa chỉ vị cố định là 54 .

Bitmap Infor: dùng để mô tả thông tin về ảnh đang dùng được lưu trữ trong tệp kích thước của phần này cố định là 40 byte.

Ý nghĩa và giá trị của từng trường trong vùng Bitmap Infor được mô tả chi tiết trong hình :

Offset (byte) Giá trị Ý nghĩa

1 -> 4 40 Số lượng byte của vùng

bitmap infor

5-> 8 Unsigned long Độ rộng của ảnh tính theo

Pixel

9->12 Unsigned long Độ cao của ảnh tính theo

Pixel

13->14 1 Number of Color Plans

15->16 Unsigned long Số bít để biểu diễn một

điểm ảnh

17->20 Unsigned long Kiểu nén

21->24 Unsigned long Độ lớn của ảnh (byte)

25->28 Unsigned long Độ phân giải của ảnh theo

chiều ngang

29->32 Unsigned long Độ phân giải của ảnh theo

chiều dọc

33->36 Unsigned long Số lượng màu trong bảng

màu

37->40 Unsigned long Số màu quan trọng

Hình 4.2: Bitmap info

Pallete Table : Bảng màu là tập các màu sử dụng trong ảnh , mỗi một màu trong ảnh được goi là mọt entry và được lưu trữ bằng 4 byte, mỗi thành phần màu được lưu trữ một byte còn một byte để dự trữ ( chứa dùng) và thứ tự là B , G, R, Reserved. Như vậy kích thước của bảng màu có thể tinh theo công thức:

Data: Vùng dữ liệu ảnh là giá trị của điểm ảnh , kích thước của vùng dữ liệu ảnh phụ thuộc và độ rộng , chiều cao và kiểu ảnh. . Với ảnh 8 bit màu thì ta có công thức

Sizeof(Data)=Width*Height

Với ảnh có số màu lớn hơn 256 ta có công thức

Sizeof(Data)=Width*Height*Bit_Number_of_Pixel

Vậy tại vùng Data là giá trị các thành phần màu cơ bản , số lượng bit dùng để biểu diễn giá trị cho từng thành phần màu có thể sẽ khác nhau phụ thuộc vào chất lượng ảnh. Ảnh 24 bit mỗi thành phần màu đựơc lưu trữ bởi 8 bit và thứ tự lưu trữ là B, G, R .

4.2. Thuật toán LSB

Least significant bit insertion : Thông tin cần được che dấu sẽ được thay thế bằng mỗi bit có trọng số thấp nhất (Least significant bit) của mỗi pixel trong bức ảnh .

Trong tất cả các bức ảnh số thì đều là hợp thành của các điểm ảnh gọi là pixel. Mỗi pixel lại có một màu sắc riêng phụ thuộc vào sự thay đổi % của 3 màu là đỏ ,xanh lục và xanh gọi là (RGB) .

Mỗi phần của 3 màu đó lại có giá trị số hóa nằm trong khoảng 0-255 .Do đó mỗi pixel thường có 24 bit .Vậy tương ứng sẽ có 256*256*256 =16,777,216 màu khác nhau .một số màu cơ bản như :

Đỏ là 255 0 0 (11111111 00000000 00000000) Xanh lục là 0 255 0 (00000000 1111111 00000000) Đen là 0 0 0 (00000000 00000000 00000000)

Trắng là 1 1 1 (11111111 1111111 1111111)

Với mỗi pixel chúng ta có thể thay thế các trọng số thấp nhất thì với mắt thường cũng không thể xác định được là có sự thay đổi .

2 hình vuông trên nhìn bằng mắt thường và có thể phóng to nhìn bằng các chương trình xem ảnh đi nữa thì chúng ta cũng không thể nào phân biệt được sự khác nhau giữa 2 hình ảnh này .

Hình 4.3: Màu xanh với mã màu (0 0 255)

Hình 4.4: Màu xanh với mã màu (0 0 254)

Có một phương pháp khá thông dụng để ẩn thông điệp vào trong một bức ảnh đó là giải thuật LSB cụ thể:

- Chúng thay thế một số bít của file ảnh gốc để ẩn tuần tự các byte của thông điệp cần ẩn vào trong bức ảnh

- Ứng dụng giải mã sẽ đọc từng bit cuối cùng của từng byte rồi tái tạo lại thông tin và chúng ta có thể nhận diện được thông điệp

4.3. Giới thiệu về chương trình demo4.3.1. Giới thiệu ngôn ngữ sử dụng 4.3.1. Giới thiệu ngôn ngữ sử dụng

Ngôn ngữ được sử dụng để cài đặt là C#.NET một ngôn ngữ mới và mạnh trong thời điểm hiện này. Với ngôn ngữ này hỗ trợ rất nhiều

trong việc cài đặt chương trình, đặc biệt với việc xử lý (trích và thay thế) các LSB bit.

4.3.2. Mã nguồn chương trình

Chương trình được viết với giao diện được xây dựng trên nền WinForm của ngôn ngữ lập trình C#.NET

Nội dung chi tiết từng file StreamProcess.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace EmbedData { class StreamProcess {

public static void Encode(Stream inStream, byte[] message, Stream outStream) { int byteRead; byte byteWrite; int i = 0; int j = 0; byte bit;

while ((byteRead = inStream.ReadByte()) != -1) {

if (i < message.Length) {

bit = BitProcess.Extract(message[i], j++);

BitProcess.Replace(ref byteWrite, 0, bit);

if (j == 8) { j = 0; i++; } }

outStream.WriteByte(byteWrite); }

}

publicstatic byte[] Decode(Stream stream, int length) {

byte[] hidden = newbyte[length]; int i = 0;

int j = 0; byte bit; int byteRead;

while ((byteRead = stream.ReadByte()) != -1) {

bit = BitProcess.Extract((byte)byteRead, 0); BitProcess.Replace(ref hidden[i], j++, bit); if (j == 8) { j = 0; i++; }

if (i == length) break; }

return hidden; }

}

publicclass FileStreamProcess {

publicstatic byte[] StreamFile(string filename) {

FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);

// Create a byte array of file stream length

byte[] ImageData = newbyte[fs.Length];

//Read block of bytes from stream into the byte array

fs.Read(ImageData, 0, System.Convert.ToInt32(fs.Length)); //Close the File Stream

fs.Close();

return ImageData; //return the byte data

}

publicstatic void Save(byte[] Bytes, string filesave) {

using (System.IO.Stream s = System.IO.File.Create(filesave)) {

s.Write(Bytes, 0, Bytes.Length); }

} } } 4.4. Chương trình demo

Phần 1 : Giấu đoạn text dữ liệu vào trong file ảnh bitmap

Hình 4.5: Ảnh gốc

Bước 1 : Giấu thông tin

Hình 4.6: Nhập thông tin muốn giấu vào ảnh

Lấy thông điệp ở đây là Nguyen Duy Thang At3b Chọn nơi chứa ảnh mới (ở đây là file Apple.bmp )

Hình 4.7: Dữ liệu được giấu trong ảnh thành công

Click Button Giấu thông tin Ta được file Apple giau tin.bmp

Hình 4.8: 2 Ảnh mới sinh ra và ảnh gốc không có sự khác biệt

Ta có thể thấy Apple giau tin.bmp sau khi được giấu thông tin không khác gì ảnh gốc Apple.bmp

Bước 2 : Lấy Dữ liệu ra khỏi ảnh

Từ file Apple giau tin.bmp ta lấy được phần trước ta sẽ tiền hành lấy thông tin đã được dấu

Từ chương trình chuyển sang tab : Lấy thông tin và chọn file Apple giau tin.bmp

Hình 4.9: Giao diện phần lấy thông tin

Click button Lấy Thông tin để lấy được dữ liệu đã dấu trong Apple giau tin.bmp

Hình 4.10: Lấy thông tin

Như ta đã thấy dữ liệu được lấy ra chính là đoạn text ta đã giấu vào Apple.bmp : Nguyen Duy Thang At3b

Phần 2 : Giấu 1 file dữ liệu vào trong file ảnh bitmap

Cũng như phần trước lấy một bức ảnh bitmap 24 bit : Anh.bmp trước khi giấu thông tin:

Hình 4.11: ảnh gốc

Ta có 1 file ảnhicon.jpg

Hình 4.12: File dữ liệu muốn giấu

Ta sẽ tiến hành giấu ảnh icon.jpg vào trong file Apple.bmp

Bước 1 : Giấu thông tin

Chạy chương trình , chọn tab Giấu File Ta lần lượt chọn

File ảnh gốc : Apple.bmp File cần giấu : icon.jpg

Click Button Giấu thông tin Ta được file Apple giau icon.bmp

Hình 4.15: Giấu file vào trong ảnh

Ta có thể thấy file mới sinh ra Apple giau icon.bmp không khác gì file gốc Apple.bmp

Bước 2 : Lấy tin

Từ file Anh3.bmpta lấy được phần trước ta sẽ tiền hành lấy thông tin đã được dấu

Từ chương trình chuyển sang tab : Lấy file và chọn file Applegiau icon.bmp

Hình 4.17: Lấy file từ ảnh được sinh ra

Hình 4.18: Lấy file

Sau khi click button Lấy File ta thấy sẽ sinh được file mới icon1.jpg

Ta có thể nhận thấy File mới được sinh ra là icon.jpg không khác so với file ban đầu là icon1.jpg

Hình 4.20: Không nhận thấy sự khác nhau giữa 2 hình

KẾT LUẬN 1. Đánh giá

Sau một khoảng thời gian nỗ lực nghiên cứu cùng với sự hướng dẫn tận tình của thầy giáo em đã bản hoàn thành được các yêu cầu đề tài. Đó là giấu

được thông tin vào trong một file ảnh và lấy thông tin từ các file ảnh có ẩn chứa thông tin trong đó. Các thông tin được giấu là một đoạn thông điệp, một file ảnh cũng có thể được giấu trong một file ảnh.

2. Phát triển và hạn chế của đề tài

Chương trình đã làm được những công việc trên và hướng của em mong muốn đó là nhúng vào một phần mềm có sẵn để bảo vệ bản quyền cho một sản phẩm nào đó. Hy vọng em sẽ được các thầy, cô chỉ bảo để phát triển thành một phần mềm thiết thực hơn nữa. Em xin chân thành cảm ơn!

TÀI LIỆU THAM KHẢO

1. Giấu tin trong dữ liệu đa phương tiện , một công nghệ mới trong bảo mật thông tin – Trần Quốc

2. Dùng Kỹ thuật giấu tin trong ảnh sử dụng các bit LSB – Thạc sỹ Lương Đức Hải.

3. Keeping secrets secrest : Steganography with .NET – www.devx.com 4. Techiniques for data hiding – W.Bender – D.Gruhl – N.Morimoto – A.Lu 5. Trang web www.wikipedia.com

6. Andersen, R.J., Petitcolas, F.A.P., On the limits of steganography. IEEE Journal of Selected Areas in Communications, Special Issue on Copyright and Privacy Protection 16 No.4 (1998) 474-481.

7.Balasubramanian, R., Bouman, C.A., Allebach, J.P.: Sequential Scalar Quantization of Color Images. Journal of Electronic Imaging 3 No.1 (1994) 45-

59.ckW.:StegoDos.ftp://ftp.csua.berkeley.edu/pub/cypherpunks/steganograph y/ stegodos.zip

8. Các nguồn khác trên internet

PHỤ LỤC Mã nguồn chương trình đầy đủ

Nội dung chi tiết StreamProcess.cs

using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace EmbedData { class StreamProcess {

public static void Encode(Stream inStream, byte[] message, Stream outStream) { int byteRead; byte byteWrite; int i = 0; int j = 0; byte bit;

while ((byteRead = inStream.ReadByte()) != -1) {

byteWrite = (byte)byteRead; if (i < message.Length) {

bit = BitProcess.Extract(message[i], j++);

if (j == 8) { j = 0; i++; } }

outStream.WriteByte(byteWrite); }

}

publicstatic byte[] Decode(Stream stream, int length) {

byte[] hidden = newbyte[length]; int i = 0;

int j = 0; byte bit; int byteRead;

while ((byteRead = stream.ReadByte()) != -1) {

bit = BitProcess.Extract((byte)byteRead, 0); BitProcess.Replace(ref hidden[i], j++, bit); if (j == 8) { j = 0; i++; } if (i == length) break; } return hidden; } }

publicclass FileStreamProcess {

publicstatic byte[] StreamFile(string filename) {

FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);

// Create a byte array of file stream length

byte[] ImageData = newbyte[fs.Length];

//Read block of bytes from stream into the byte array

fs.Read(ImageData, 0, System.Convert.ToInt32(fs.Length)); //Close the File Stream

fs.Close();

return ImageData; //return the byte data

}

publicstatic void Save(byte[] Bytes, string filesave) {

using (System.IO.Stream s = System.IO.File.Create(filesave)) { s.Write(Bytes, 0, Bytes.Length); } } } } BitProcess.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace EmbedData { class BitProcess { //Thay The

publicstatic void Replace(ref byte b, int pos, byte value) {

b = (byte)(value == 1 ? b | (1 << pos) : b & ~(1 << pos)); }

//Lay Gia tri

publicstatic byte Extract(byte b, int pos) {

return (byte)((b & (1 << pos)) >> pos); } } } Code.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace EmbedData

{

class Code {

public static void CreateFile(string fileName, string stegoFileName,

string message) {

FileStream inStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

int offset = 54; //So bit cua Header + Info trong file bmp

byte[] header = new byte[offset]; inStream.Seek(0, 0);

// Doc header tu inStream

inStream.Read(header, 0, offset);

FileStream outStream = new FileStream(stegoFileName, FileMode.Create, FileAccess.Write);

//Ghi phan header cua inStream trong outStream

outStream.Write(header, 0, offset);

UnicodeEncoding unicode = new UnicodeEncoding(); // Them header + info cua Image vao Message

byte[] messageBytes = AddHeadMessage(unicode.GetBytes(message));

inStream.Seek(offset, 0); // Thay the bit

StreamProcess.Encode(inStream, messageBytes, outStream); inStream.Close();

outStream.Close(); }

privatestatic byte[] AddHeadMessage(byte[] messageBytes) {

int len = messageBytes.Length;

byte[] bLen = BitConverter.GetBytes(len); byte[] ret = newbyte[len + bLen.Length]; for (int i = 0; i < bLen.Length; i++)

ret[i] = bLen[i];

for (int i = 0; i < messageBytes.Length; i++) ret[i + bLen.Length] = messageBytes[i]; return ret;

}

publicstatic string ExtractHiddenMessage(string fileName) {

Stream inStream = new (fileName, FileMode.Open, FileAccess.Read); FileStream

int offset = 54;

inStream.Seek(offset, 0);

da giau)

byte[] bLen = StreamProcess.Decode(inStream, 4);

//Do dai cua message

int len = BitConverter.ToInt32(bLen, 0);

inStream.Seek(offset + 4 * 8, 0); // Lay message

byte[] buffer;

buffer = StreamProcess.Decode(inStream, len);

UnicodeEncoding unicode = new UnicodeEncoding(); string hiddenMessage = unicode.GetString(buffer); inStream.Close();

return hiddenMessage; }

publicstatic void ExtractFileHidden(string fileName,string filehidden) {

Stream inStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

inStream.Seek(offset, 0);

// Lay 4 bytes trong inStream (4 byte nay chua header cua message da giau)

byte[] bLen = StreamProcess.Decode(inStream, 4);

//Do dai cua message

int len = BitConverter.ToInt32(bLen, 0);

inStream.Seek(offset + 4 * 8, 0); // Lay message

byte[] buffer;

buffer = StreamProcess.Decode(inStream, len); FileStreamProcess.Save(buffer, filehidden); inStream.Close();

}

public static void CreatedFileinFile(string fileName, string

stegoFileName, string filehidden) {

FileStream inStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

int offset = 54; //So bit cua Header + Info trong file bmp

byte[] header = new byte[offset]; inStream.Seek(0, 0);

// Doc header tu inStream

inStream.Read(header, 0, offset);

FileStream outStream = new FileStream(stegoFileName, FileMode.Create, FileAccess.Write);

//Ghi phan header cua inStream trong outStream

outStream.Write(header, 0, offset);

UnicodeEncoding unicode = new UnicodeEncoding(); // Them header + info cua Image vao Message

byte[] messageBytes = AddHeadMessage(FileStreamProcess.StreamFile(filehidden));

inStream.Seek(offset, 0); // Thay the bit

StreamProcess.Encode(inStream, messageBytes, outStream); inStream.Close(); outStream.Close(); } } }

Một phần của tài liệu Đề tài Ứng dụng ẩn mã và giấu tin trong ảnh (Trang 36)

Tải bản đầy đủ (DOC)

(66 trang)
w