Cấu trúc chương trình

Một phần của tài liệu (LUẬN văn THẠC sĩ) nghiên cứu phối hợp hai phương pháp nén và mã hóa thông tin (Trang 87 - 92)

Chương 4: PHỐI HỢP HAI PHƯƠNG PHÁP NÉN VÀ MÃ HOÁ THÔNG TIN

4.3 CHƯƠNG TRÌNH THỬ NGHIỆM

4.3.2.2 Cấu trúc chương trình

Chương trình cho phép nén, mã hoá trên nhiều loại file khác nhau: văn bản (.doc, xls, pptt, txt…), ảnh (bitmap, Jpg…), các file video… Các loại file khác nhau có định dạng và cấu trúc file cũng khác nhau do đó quá trình giãi mã và giải nén ngoài việc giữ nguyên nội dung file gốc phải đảm bảo cả về mặt định dạng và cấu trúc file ban đầu

1. Xây dựng lớp ConvertStringTobyte.cs gồm các phương thức:

- readfileTostring: Đọc tệp có định dạng tuỳ ý trả về một xâu ký tự

Đọc file theo từng bit, chuyển dãy bit thành dãy số nguyên sau đó chuyển số nguyên thành các ký tự và ghép thành một xâu

- Createfile: Từ xâu ký tự ghi thành tệp gốc (giữ nguyên nội dung và cấu trúc) Chuyển mỗi ký tự trong xâu thành một số nguyên, đổi các số nguyên thành các bit sau đó ghi tệp theo các bit.

- Ghi file text:

+ Input: xâu ký tự, đường dẫn + Output: tệp văn bản

2. Nén dữ liệu bằng phương pháp LZW (Lempel - Zip - Welch) – Xây dựng lớp LZW.cs a. Nén dữ liệu:

Input: đường dẫn tệp tin cần nén

Output: Tệp tin đã nén (với tên: tên file gốc + phần mở rộng lzw) Tệp tin nén sẽ đƣợc đặt cùng thƣ mục với tệp tin gốc

Trong quá trình nén sử dụng một bảng băm để lưu từ điển nén theo thuật toán LZW đã trình bày trong phần 3.3.2.2 mục 3.

b. Giải nén dữ liệu:

+ Input: đường dẫn tệp cần tin nén;

+ Output: tệp tin giải nén (có tên: tên của tập tin ban đầu) Tệp tin giải nén đƣợc đặt trong cùng thƣ mục với tệp tin nén

Quá trình giải nén sử dụng từ điển đƣợc xây dựng dần từ văn bản đã xét. Từ

lần trong bản nén điều này ảnh hưởng nhiều đến hiệu quả nén. Để khắc phục nhược điểm này dựa vào ý tưởng của phương pháp nén theo mô hình thống kê, từ nào xuất hiện nhiều lần đƣợc mã hoá bằng từ mã ngắn hơn. Nhƣ vậy ở đây sau khi xây dựng từ điển và bản mã cần thêm một công đoạn kiểm tra lại bản mã thống kê số lần lặp lại của các từ mã sau đó đánh lại số thứ tự của từ điển đồng thời thay thế các từ mã trong bản nén. Trước khi thay đổi bản mã và từ điển cần sử dụng mảng để lưu lại ánh xạ thay đổi giữa từ mã cũ và từ mã mới

Quá trình giải nén các kí tự không đƣợc ghi ngay ra tệp tin giải nén mà chuỗi ký tự sẽ được lưu thành một xâu, xâu ký tự được chuyển về dạng bit để ghi tệp theo đúng cấu trúc ban đầu.

3. Nén bằng phương pháp GZIP – Xây dựng lớp: Gzip.cs

- Sử dụng thƣ viện có sẵn của C#.Net: System.Io.Compression

- Sử dụng lớp có sẵn trong thư viện: Gzipstream gồm hai phương thức CompressMode và DecompressMode

- Phương thức Compress

+ Input: đường dẫn tệp tin cần nén; đường dẫn tệp tin sau khi nén + Output: tệp tin nén (tên file nén = tên tệp ban đầu + phần mở rộng .gzip)

void Compress(String input, String output)

fileOutput = new FileStream(output, FileMode.Create, FileAccess.Write);

gzipStream = new GZipStream(fileOutput, CompressionMode.Compress, true);

fileInput = new FileStream(input, FileMode.Open, FileAccess.Read, FileShare.Read);

buffer = new byte[fileInput.Length];

gzipStream.Write(buffer, 0, buffer.Length);

- Nhƣ đã trình bày trong phần mở đầu 4.3.2.2 nội dung tệp tin nén sẽ đƣợc chuyển thành một mảng số nguyên (byte) trước khi áp dụng giải thuật nén.

- Tệp tin nén đƣợc đặt trong cùng thƣ mục với tệp tin ban đầu - Phương thức Decompress

+ Input: đường tệp tin nén, đường dẫn tệp tin giải nén + Output: tệp tin nén

fileInput = new FileStream(input, FileMode.Open, FileAccess.Read);

fileOutput = new FileStream(output, FileMode.Create, FileAccess.Write);

gzipStream = new GZipStream(fileInput, CompressionMode.Decompress, true);

fileOutput.Write(buffer, 0, count);

4. Huffman – xây dựng hai lớp: HuffmanTree.cs và Node.cs a. Lớp HuffmanTree.cs

Phương thức: Build (string)

Trong phương thức sử dụng kiểu từ điển để lưu trữ các kí tự có trong xâu cùng với số lần xuất hiện của kí tự đó trong xâu

Xây dựng các cây con từ danh sách kí từ vừa lưu trữ trong từ điển Xây dựng cây nhị phân đầy đủ từ các cây con

Phương thức: BitArray Encode (string);

Mã hoá xâu kí tự trả về một dãy bít nhị phân, trong phương thức có gọi dến phương thức Traverse(char symbol, List<bool> data) của lớp Node.

Để thu đƣợc bản mã cần đổi dãy bit về xâu kí tự và ghi lại vào file nén.

Phương thức String Decode (BitArray);

Từ dãy bit giải mã về xâu kí tự sử dụng cây nhị phân đã xây dựng b. Node.cs

Gồm có các thuộc tính:

char Symbol: ký tự của node int Frequency: trọng số của node Node Right: cây con trái

Node Left: cây con phải

Phương thức: Traverse(char symbol, List<bool> data): trả về dãy bit để mã hoá ký tự symbol.

Trong phương thức này có sử dụng kỹ thuật đệ qui để tìm ra dãy bit mã hoá kí tự cần tìm:

if (Left != null)

List<bool> leftPath = new List<bool>();

leftPath.AddRange(data);

leftPath.Add(false);

left = Left.Traverse(symbol, leftPath);

if (Right != null)

List<bool> rightPath = new List<bool>();

rightPath.AddRange(data);

5. Mã hoá tệp tin (AES Encryption)

- Thuật toán mã hoá AES đƣợc đặt trong lớp AES.cs

- Trong C#. Net có thƣ viện System.Security.Cryptography; hỗ trợ mã hoá tệp tin bằng thuật toán AES

a. Mã hoá - thủ tục Encrypt

Input: bản rõ, khoá AES, (độ dài khoá) Output: bản mã

Để chuyển một chuỗi thành một dãy byte để phù hợp với phép mật hóa đối xứng sử dụng phương thức PasswordDeriveBytes. Có nhiều cách để chuyển một chuỗi thành một dãy byte bằng các kỹ thuật khác, tuy nhiên, cách tiếp cận đó không đủ bảo mật. Ví dụ, hầu hết các password đều tương đối ngắn và sử dụng có giới hạn các ký tự (chữ cái và số). Điều này làm giảm sức mạnh của các khóa đƣợc sinh ra. Tuy nhiên, bạn có thể sử dụng một giá trị chuỗi làm seed cho một bộ sinh số ngẫu nhiên, việc này có thể sinh ra một dãy byte với độ bảo mật cao có thể sử dụng làm khóa. Khi tạo một đối tƣợng PasswordDeriveBytes, cần cung cấp password và giá trị salt cho hàm khởi dựng. Salt là một dãy ngẫu nhiên các byte. Nó đƣợc kết hợp với password khi sinh ra khóa. Nếu sử dụng một giá trị salt khác 0, bạn có thể chống chọi với kiểu tấn công từ điển (dictionary attack), trong đó kẻ tấn công truy tìm một khóa cho mỗi từ trong từ điển và cố sử dụng danh sách các khóa được-tạo-trước này để giải mật hóa dữ liệu.

Vấn đề ở chỗ kẻ tấn công sinh ra danh sách khóa với giả định là không có giá trị salt.

Khi sử dụng một giá trị salt, kẻ tấn công cần phải tìm ra nó rồi mới tạo ra danh sách khóa.

Quá trình mã hoá gồm các bước:

Tạo khoá hợp lệ cho quá trình mã hoá:

PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[]

{0x00, 0x01, 0x02, 0x1C, 0x1D, 0x1E, 0x03, 0x04, 0x05, 0x0F, 0x20, 0x21, 0xAD, 0xAF, 0xA4});

Chuyển văn bản mã hoá về dãy byte

byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(Data);

Mã hoá dãy byte với cặp khoá hợp lệ vừa tạo ra và trả về xâu ký tự.

byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(16), pdb.GetBytes(16));

return Convert.ToBase64String(encryptedData);

b. Giải mã - thủ tục Desecrypt

- Quá trình giải mã gồm các bước - Tạo khoá hợp lệ cho quá trình giải mã:

PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[]

{0x00, 0x01, 0x02, 0x1C, 0x1D, 0x1E, 0x03, 0x04, 0x05, 0x0F, 0x20, 0x21, 0xAD, 0xAF, 0xA4});

- Chuyển văn bản mã hoá về dãy byte

byte[] cipherBytes = Convert.FromBase64String(Data);

- Giải mã dãy byte với cặp khoá hợp lệ vừa tạo ra và trả về xâu ký tự.

byte[] decryptedData = Decrypt(cipherBytes, pdb.GetBytes(16), pdb.GetBytes(16)) return System.Text.Encoding.Unicode.GetString(decryptedData);

6. Mã hoá khoá công khai RSA

- Sử dụng thƣ viện System.Security.Cryptography; của C#.Net. Trong thƣ viện này sử dụng lớp RSACryptoServiceProvider:

- Tạo khoá bí mật RSA RSAProvider.ToXmlString(true) - Tạo khoá công khai RSA RSAProvider.ToXmlString(false) - Đọc khoá công khai từ tệp Xml:

rsaCryptoServiceProvider.FromXmlString( xmlString ) - Đọc khoá bí mật từ tệp xml

rsaCryptoServiceProvider.FromXmlString( xmlString )

- Mã hoá từng khối dữ liệu với đầu vào là một dãy byte và trả về dãy byte tương ứng, sau đó dãy byte này đƣợc chuyển về một xâu kí tự của bản mã

byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt( tempBytes, true) stringBuilder.Append( Convert.ToBase64String( encryptedBytes ) )

- Giải mã từng từng khối dữ liệu với đầu vào là một dãy byte và trả về dãy byte tương ứng sau đó dãy byte này được chuyển thành xâu kí tự trong bản rõ

arrayList.AddRange( rsaCryptoServiceProvider.Decrypt( encryptedBytes, true ) );

return Encoding.UTF32.GetString_

( arrayList.ToArray( Type.GetType( "System.Byte" ) ) as byte[] );

Một phần của tài liệu (LUẬN văn THẠC sĩ) nghiên cứu phối hợp hai phương pháp nén và mã hóa thông tin (Trang 87 - 92)

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

(99 trang)