Hoạt động giải mã là quá trình ngƣợc lại với hoạt động mã hóa. Tƣơng ứng với 4 hàm sử dụng trong quá trình mã hóa ta có 4 hàm sử dụng trong quá trình giải mã: + InvSubBytes(): Thay thế tất cả phần từ của ma trận trạng thái bằng việc áp dụng InvS – Box lên từng phần đó
+ InvSiftRows(): Hoán vị dòng thứ i của ma trận trạng thái i bƣớc về bên phải, mỗi bƣớc dịch một byte
+ InvMixColumns():Thực hiện phép nhân ma trận cố định (nghịch đảo của ma trận cố định sử dụng trong MixColumns()) với ma trận trạng thái, trong đó phép nhân ma trận cũng dựa trên các phép toán cộng và nhân byte đã định nghĩa ở trên
State = e d b b e d d b e d b e 0 09 0 0 0 0 09 0 0 0 0 09 09 0 0 0 x State
+ Toán tử ngƣợc AddRowKey() là bản thân nó (áp dụng hai lần liên tiếp toán tử này thì ma trận trạng thái không thay đổi
Giả mã hoạt động giải mã AES
AES_Decryption(Input, key, OutPut) Begin State: = Input; r:= 10; AddRoudKey(); InvSiftRows(); InvSubBytes(); For i: = 9 downto 1 do AddRoudKey(); InvMixColumns(); InvSiftRows(); InvSubBytes(); EndFor; r: = 0; AddRowKey(); End;
Chương 3: PHƢƠNG PHÁP NÉN DỮ LIỆU 3.1 TỔNG QUAN VỀ NÉN DỮ LIỆU 3.1.1 Mã nén dữ liệu
3.1.1.1 Nén dữ liệu, bít trung bình
1/. Nén dữ liệu
a/ Khái niệm nén dữ liệu
Nén là một quá trình giảm lƣợng không gian cần thiết để biểu diễn cùng một lƣợng thông tin cho trƣớc. Ngƣời ta còn gọi nén là biến đổi một luồng ký hiệu thành một luồng các từ mã.
Quá trình nén nhƣ sau:
Hình 3.1: Quá trình nén dữ liệu
Trong đó:
Văn bản là văn bản ban đầu cần nén.
Mô hình là tập hợp các chữ cái cùng quy tắc đƣợc sử dụng để xử lý các chữ cái vào và đƣa ra các từ mã. Một mô hình sẽ xác định chính xác xác suất xuất hiện của từng chữ cái và một bộ mã sẽ tạo ra các từ mã dựa trên xác suất đó.
Mã hoá là chỉ quá trình thay thế các chữ cái trong văn bản ban đầu bằng các từ mã tƣơng ứng để đƣa ra bản mã chính xác.
Nhƣ vậy, quá trình nén diễn ra nhƣ sau: quá trình mô hình căn cứ vào văn bản cần nén sẽ tạo ra các từ mã. Sau đó, từ bộ từ mã vừa tạo đƣợc và văn bản ban đầu quá trình nén sẽ đƣa ra bản mã.
Mã hoá và mô hình là hai giai đoạn hoàn toàn khác nhau vì trong giai đoạn mô hình có rất nhiều cách để xử lý các chữ cái của văn bản mà cùng sử dụng một phƣơng pháp xây dựng mã để cho ra các từ mã.
Nếu bản mã có kích thƣớc nhỏ hơn văn bản thì phƣơng pháp nén đó có hiệu quả.
Bản mã Văn bản
Mô hình
Ví dụ
Chúng ta sử dụng cùng phƣơng pháp mã Huffman cho hai mô hình khác nhau: Mô hình 1: dựa trên xác suất độc lập của từng chữ cái xuất hiện bất kì trong văn bản.
Mô hình 2: cần tính đƣợc xác suất phụ thuộc dựa trên những chữ cái nhận đƣợc lúc đó trong văn bản.
Do mô hình khác nhau nên cùng sử dụng mã Huffman để đƣa ra từ mã nhƣng hiệu quả nén của chúng rất khác nhau.
Tuy nhiên, chúng ta vẫn quen dùng từ mã hoá để chỉ cho cả quá trình nén văn bản mặc dù đó chỉ là một giai đoạn của một quá trình nén.
Ngƣời ta thƣờng mã hoá thông qua các từ mã của một bảng chữ cái nào đó. Có thể có nhiều thuật toán nén dữ liệu khác nhau. Mỗi thuật toán có một kiểu dữ liệu nhất định và cùng một số modem có đặc điểm nén thích ứng có nghĩa là chúng có khả năng chọn thuật toán nén thích hợp phụ thuộc vào kiểu dữ liệu cần nén. Trong số các cách mã thì cách nào mã ngắn hơn chúng ta nói là nó nén tốt hơn (so với cách mã khác).
2/. Bít trung bình
Chúng ta thƣờng dùng trình nén để nén các file, tức là các văn bản đƣợc tạo ra từ 256 byte. Nén một file nhiều lần liên tiếp thì đến một lúc nào đó chúng ta cũng sẽ thu đƣợc một file mà trình nén này không thể thu nhỏ lại đƣợc nữa. Bởi vì, nếu không chúng ta sẽ nén đƣợc file ấy xuống thành một file không có bít nào cả.
Từ đó, chúng ta có khẳng định: Với mọi thuật toán mã các file văn bản luôn tồn tại một văn bản mà nó không thể nén đƣợc thành file có dung lƣợng nhỏ hơn.
Từ khẳng định trên suy ra không thể vạch định ra đƣợc một gianh giới rõ ràng giữa một bên là mã hoá và một bên là mã nén. Để đánh giá khả năng nén của một thuật toán chúng ta đƣa ra khái niệm về số bít trung bình cần thiết để ghi lại một chữ cái của văn bản.
3.1.1.2 Mã tổng và mã phân tách 1/. Mã tổng
Định nghĩa. Văn bản tổng
Cho A và B là hai văn bản. Tổng của A + B là một văn bản mới thu đƣợc từ A viết tiếp B vào bên phải của A. Nhƣ vậy độ dài của tổng các văn bản là tổng của các độ dài của chúng.
Hình 3.2: Văn bản tổng
Định nghĩa. Mã tổng
Một mã đƣợc gọi là mã tổng nếu nhƣ bản mã của tổng các văn bản là tổng các bản mã.
Hình 3.3: Mã tổng
Trong định nghĩa cho mã tổng ta đã sử dụng khái niệm “tổng của các văn bản”. Nếu bản mã của văn bản “a” là f(a), của văn bản b là f(b) thì bản mã của “ab” là “f(a)f(b)”, bản mã của “ba” là “f(b)f(a)”.
Xét mã tổng trên bảng chữ cái Σ = {a1, a2, ...., am}. Mỗi chữ cái a1, a2, ..., am có từ mã tƣơng ứng. Từ mã của các chữ cái xác định ánh xạ f : Σ → M, từ tập các chữ cái vào tập các xâu bít “0/1”. Nhƣ vậy với mọi ai Σ, xâu bít f(ai) là từ mã của ai, độ dài xâu bít f(ai) đƣợc ký hiệu là (ai).
Theo định nghĩa mã tổng thì xâu các chữ cái = 1 2... n tƣơng ứng duy nhất với xâu bít có dạng f( ) = f( 1)f( 2)...f( n). Bản mã f( ) có độ dài L( )=
n i i 1 ) ( bit. + = + = 1001010 + 111000 = 1001010111000 b¶n m· v¨n b¶n
2/. Mã phân tách
Từ đây chúng ta chỉ đề cập đến các mã tổng nhị phân. Nếu các từ mã có độ dài cố định thì ta luôn giải mã đƣợc. Nhƣng nếu độ dài của từ mã thay đổi thì không phải với cách mã nào cũng có thể giải mã đƣợc.
Xét cách mã sau: a -> 100
b -> 1000 c -> 0
Bản mã của “ac” và b đều là dãy bít “1000”. Nhƣ vậy khi nhận đƣợc chuỗi bít 1000 chúng ta không thể biết đƣợc rằng văn bản ban đầu là “b” hay là “ac”.
Điều kiện quan trọng của việc tạo mã là cho phép khi nhận đƣợc bản mã, chúng ta phải tách ra đƣợc thành các thành phần cơ bản là các từ mã và cách tách này phải là duy nhất và đúng đắn. Tính phân tách đƣợc đƣa ra dƣới đây sẽ đảm bảo cho điều này.
3.1.2 Định lý Shannon
Cùng một dữ liệu có thể có nhiều cách mã hoá. Trong số các cách mã hoá khác nhau có thể có cách mã hoá mà thu đƣợc bản mã ngắn hơn.
Nén dữ liệu không phải là việc các dữ liệu bị ghi nén lại. Bản chất của các thuật toán nén dữ liệu là ghi lại văn bản (mã hoá lại văn bản) ở dạng khác.
Khi đó xuất hiện hai câu hỏi:
Câu hỏi 1: Có thể nén một văn bản nhỏ đến bao nhiêu cũng đƣợc hay là có một giới hạn nào đó mà chúng ta không thể vƣợt qua đƣợc.
Câu hỏi 2: Có hay không một thuật toán nén tốt nhất.
Điều kiện đầu tiên để nén đƣợc văn bản là các văn bản khác nhau thì có các file nén khác nhau. Bởi nếu không thì chúng ta không thể khôi phục lại văn bản nguồn. Mọi văn bản không thể nén lại thành một file chỉ có 1 bít vì số lƣợng các file có một bít là 2. Một qui trình nén nhƣ vậy thì chỉ có thể dùng để nén hai văn bản mà thôi, đến văn bản thứ ba là nội dung file nén sẽ bị trùng lặp. Vậy thì không thể nén một văn bản nhỏ tuỳ ý đƣợc.
Shannon là ngƣời đầu tiên chứng minh đƣợc sự tồn tại một giới hạn nén cho mỗi văn bản. Một văn bản thực ra thì chỉ có thể nén đến một giới hạn nhất định, giới hạn ấy chúng ta gọi là lƣợng tin của văn bản. Lƣợng tin chỉ phụ thuộc vào bản thân
văn bản chứ không phụ thuộc vào thuật toán nào. Mọi thuật toán đều không thể nén một văn bản đến một file nhỏ hơn lƣợng tin mà văn bản có. Sau đây chúng ta sẽ làm quen với khái niệm lƣợng tin. Lƣợng tin còn đƣợc gọi là entropy.
Ví dụ
Giả sử văn bản của chúng ta chỉ có 4 chữ cái “a”, “b”, “c”, “d”. Nếu chúng ta dùng cách mã hoá mà các từ mã có cùng độ dài thì ta có thể mã chữ cái “a” là 00, “b” là 01, “c” là 10, “d” là 11. Nhƣ vậy một văn bản gồm 1000 chữ cái sẽ phải mã bởi 2000 bít. Số bít cho một chữ cái là 2 bít.
Nếu nhƣ đƣợc biết chữ cái “a” xuất hiện 97% trong số các trƣờng hợp, còn các chữ cái “b”, “c”, “d” chỉ xuất hiện có 1%.
Ta xét ba cách mã sau đây:
Cách 1:
Chúng ta có thể mã chữ cái “a” là 0, chữ cái “b” là 110, chữ cái “c” là 100, chữ cái “d” là 111. Trung bình một văn bản có 1000 chữ cái thì có 970 chữ “a” và 10 chữ “b”, 10 chữ “c”, 10 chữ “d”. Văn bản gồm 1000 chữ cái khi nén lại sẽ dài trung bình 1*970 + 3*10 + 3*10 + 3*10 = 1060 bít.
Sự khác nhau giữa 1060 bít và 2000 bít là do chúng ta mã chữ cái hay gặp bằng một dãy bít ngắn hơn còn các chữ cái ít gặp bằng các dãy bít dài hơn.
Nhƣ vậy là chỉ do thay đổi cách mã mà chúng ta, thay vì phải lƣu trữ 2000 bít dữ liệu thì nay chỉ cần 1060 bít. Hệ số nén văn bản là gần 2 lần. Số bít trung bình cho một chữ cái là 1060 : 1000 1 bít. Liệu 1060 bít đã là giới hạn chƣa, có cách nào mã nén tốt hơn không? Chúng ta xét cách mã thứ hai.
Cách 2: Chúng ta mã nhƣ sau: aa 0 ba 1100 bc 11111 db 1000100 ab 1001 ca 1101 dc 1000000 cc 1000101 ac 1010 da 1110 bd 1000001 bb 1000110 ad 1011 cb 11110 cd 1000011 dd 1000111
Một văn bản có 1000 chữ cái thì có 500 cặp các chữ cái. Số lƣợng trung bình cho mỗi cặp chữ cái là:
Số lƣợng mỗi loại Số bít cần để mã
aa 500*0.9409 = 470.45 470.45*1 = 470.45
ab, ac, ad, ba, ca, da 500*0.0097 = 4.85 4.85*4 = 19.4
cb, bc 500*0.0001 = 0.05 0.05*5 = 0.25
dc, bd, cd, db, cc, dd, bb 500*0.0001 = 0.05 0.05*7 = 0.35
Văn bản gồm 1000 chữ cái a, b, c, d với tỉ lệ nhƣ trên thì trung bình sẽ mã bằng dãy bít có độ dài 470.45 + 19.4*6 + 0.25*2 + 0.35*7 = 589.8 bít. Hệ số nén là 39 . 3 8 . 589 2000
tức là khoảng hơn 3 lần. Số bít trung bình cho một chữ cái là 59 . 0 1000 8 . 589 bít.
Nhƣ vậy, nhóm các chữ cái lại để mã thì sẽ tạo ra đƣợc một phƣơng pháp mã tốt hơn. Mỗi nhóm các chữ cái đƣợc ký mã bằng một nhóm bít 0/1. Các nhóm bít dùng để mã này phải đƣợc chọn thế nào để từ dãy bít này chúng ta có thể khôi phục lại đƣợc các nhóm chữ cái, tức là cho phép khôi phục lại văn bản ban đầu. Điều tối thiểu để làm đƣợc việc này là các nhóm chữ cái khác nhau thì phải đƣợc mã bởi các nhóm bít 0/1 khác nhau.
Cách 3:
Chúng ta nhóm các chữ cái thành từng nhóm, mỗi nhóm có 100 chữ cái thì các nhóm chữ cái hay gặp phải là các nhóm 97 chữ “a” và các chữ khác “b”, “c”, “d” mỗi chữ chỉ gặp một lần. Có tất cả 100*99*98 nhóm nhƣ vậy. Vì rằng 219
< 100*99*98 < 220 nên chúng ta có thể sử dụng các nhóm bít có độ dài 20 bít để ký mã các nhóm 100 chữ cái nói trên, nhƣng không thể sử dụng các nhóm bít chỉ có độ dài 19 bít. Nhƣ vậy về trung bình, một văn bản có 1000 chữ cái “a”, “b”, “c”, “d” với tỉ lệ xuất hiện nhƣ trên thì có thể mã thành dãy bít có độ dài nhỏ hơn 200 bít, nhƣng không thể mã lại thành một dãy ngắn hơn 190 bít. So với cách mã đầu tiên thì nén khoảng 10 lần. Số bít trung bình cho một chữ cái là 200 : 1000 = 0.2.
Định lý. Shannon
Xét các văn bản đƣợc tạo ra theo cách chọn ngẫu nhiên các chữ cái Σ = {a1, a2, ..., am} với xác suất xuất hiện tƣơng ứng p1 p2 .... pm > 0.
1. Với mọi mã nhị phân
a. Bit trung bình của mã thoả mãn
n A L p n ( ) ( ) 1 i m i pi p 1 log2 1
b. Với hầu hết các văn bản bít trung bình (cho một chữ cái) của văn bản không nhỏ hơn m
i 1pi 2 pi
1 log
2. Tồn tại mã nhị phân cho từng khối k chữ cái có tính phân tách sao cho bít trung bình (cho một chữ cái) của nó nằm giữa m
i 1pi 2 pi 1 log và m i pi pi k 1 2 1 log 1 . Định lý khẳng định rằng: “entropy đúng là giới hạn nhỏ nhất có thể mà bít trung bình của một mã nén nhị phân có thể đạt đƣợc” cho dù mã đƣợc tạo ra theo cách nào đi chăng nữa.
3.2 MÔ HÌNH THỐNG KÊ 3.2.1 Mô hình thống kê tĩnh
Dạng đơn giản nhất của mô hình thống kê tĩnh là một bảng tĩnh liệt kê các giá trị xác suất theo cách tính thông thƣờng. Trƣớc đây, do việc phân tích và xây dựng mã Huffman rất tốn thời gian, nên ngƣời ta chỉ phân tích một lần đối với các dữ liệu điển hình để có đƣợc một bảng đếm số lần xuất hiện của từng ký hiệu. Dựa vào kết quả đó, một cây mã Huffman tĩnh đƣợc xây dựng và lƣu trữ để có thể đƣợc sử dụng nhiều lần. Mô hình nhƣ vậy đƣợc gọi là mô hình thống kê tĩnh (Static Statiscal Model).
Việc sử dụng một mô hình tĩnh vạn năng cho nhiêu kiểu dữ liệu rõ ràng là có nhiều hạn chế. Nếu dữ liệu vào không thích hợp với mô hình thì hiệu quả nén sẽ giảm, thậm chí sẽ có kích thƣớc lớn hơn dữ liệu vào (gọi là nở đầu vào). Do đó một cải tiến tiếp theo là xây dựng mô hình tĩnh cho nhiều kiểu dữ liệu.
Việc xây dựng mô hình tĩnh riêng sẽ có thuận lợi là mang lại hiệu suất nén cao. Nhƣng nhƣợc điểm là lại cần lƣu trữ thêm một lƣợng dữ liệu nhất định (cấu trúc của cây mã) trƣớc khi lƣu trữ bản mã. Nếu cấu trúc của cây mã vào không lớn lắm vào khoảng 256B so với lƣợng số lƣợng dữ liệu cần nén vài trăm KB thì mô hình tĩnh riêng là hiệu quả. Nhƣng nếu cấu trúc của cây mã tăng lên mức không thể chấp nhận đƣợc so với mục tiêu nén dữ liệu (cỡ khoảng 64KB) thì mô hình tĩnh riêng không phù hợp.
3.2.2 Mô hình thống kê động
Để khắc phục những nhƣợc điểm của mô hình thống kê tĩnh, mô hình thống kê động ra đời với số liệu thống kê đối với dữ liệu cần mã hoá không phải lƣu trữ trƣớc mà liên tục đƣợc tích luỹ và sửa đổi trong suốt quá trình mã hoá và giải mã.
Hình 3.4: Mã hoá theo mô hình thống kê động
Đọc ký hiệu Mã hoá ký hiệu Xuất từ mã
Mô hình Cập nhật mô hình
Hình 3.5: Giải mã hoá theo mô hình thống kê động
Điểm đáng chú ý trong hai sơ đồ trên là khối cập nhật mô hình. Khối này phải hoạt động chính xác nhƣ nhau cả khi mã hoá và khi giải mã. Sau khi một ký hiệu hoặc