Phương pháp mã hoá ñộ dài loạt

Một phần của tài liệu MÃ HOÁ NÉN DỮ LIỆU VÀ MÃ HOÁ CÓ KHẢ NĂNG PHÁT HIỆN SAI VÀ SỬA SAI (Trang 33 - 96)

Loại dư thừa ựơn giản nhất trong một tập tin là các ựường chạy dài gồm các kắ tự lặp lại, ựiều này thường thấy trong các tập tin ựồ hoạ bitmap, các vùng dữ liệu hằng của các tập tin chương trình, một số tập tin văn bản...

Vắ dụ, xét chuỗi sau:

AAAABBBAABBBBBCCCCCCCCDABCBAAABBBBCCCD

Chuỗi này có thể ựược mã hoá một cách cô ựọng hơn bằng cách thay thế

chuỗi kắ tự lặp lại bằng một thể hiện duy nhất của kắ tự lặp lại cùng với một biến ựếm số lần kắ tự ựó ựược lặp lại. Ta muốn nói rằng chuỗi này gồm bốn chữ A theo sau bởi ba chữ B rồi lại theo sau bởi hai chữ A, rồi lại theo sau bởi năm chữ B... Việc nén một chuỗi theo phương pháp này ựược gọi là mã hoá

ựộ dài loạt. Khi có những loạt chạy dài, việc tiết kiệm có thể là ựáng kể. Có nhiều cách ựể thực hiện ý tưởng này, tuỳ thuộc vào các ựặc trưng của ứng

dụng (các loạt chạy có khuynh hướng tương ựối dài hay không? Có bao nhiêu bit ựược dùng ựể mã hoá các kắ tựựang ựược mã?).

Nếu ta biết rằng chuỗi của chúng ta chỉ chứa các chữ cái, thì ta có thể mã hoá biến ựếm một cách ựơn giản bằng cách xen kẽ các con số với các chữ cái. Vì vậy chuỗi kắ tự trên ựược mã hoá lại như sau:

4A3BAA5B8CDABCB3A4B3CD

Ở ựây "4A" có nghĩa là "bốn chữ A"... Chú ý là không ựáng ựể mã hoá các loạt chạy có ựộ dài 1 hoặc 2 vì cần ựến hai kắ tựựể mã hoá.

Đối với các tập tin nhị phân thì ý tưởng ở ựây là lưu lại các ựộ dài loạt, tận dụng sự kiện các loạt chạy thay ựổi giữa 0 và 1 ựể tránh phải lưu chắnh các số 0 và 1 ựó. Điều này giả ựịnh rằng có một vài loạt chạy ngắn (ta tiết kiệm các bit trên một loạt chạy chỉ khi ựộ dài của ựường chạy là lớn hơn số

bit cần ựể biễu diễn chắnh nó trong dạng nhị phân), nhưng khó có phương pháp mã hoá ựộ dài loạt nào hoạt ựộng thật tốt trừ phi hầu hết các loạt chạy

ựều dài.

Việc mã hoá ựộ dài loạt cần ựến các biễu diễn riêng biệt cho tập tin và cho bản ựã ựược mã hoá của nó, vì vậy nó không thể dùng cho mọi tập tin, vắ dụ, phương pháp nén tập tin kắ tự ở trên sẽ không dùng ựược ựối với các chuỗi kắ tự có chứa số. Nếu những kắ tự khác ựược sử dụng ựể mã hoá các số ựếm, thì nó sẽ không làm việc với các chuỗi chứa các kắ tựựó. Giả sử ta mã hoá bất kì kắ tự nào từ một bảng chữ cái cốựịnh bằng cách chỉ dùng các kắ tự

từ bảng chữ cái ựó, giả sử ta chỉ có 26 chữ cái trong bảng chữ cái (và cả

khoảng trống) ựể làm việc.

Để có thể dùng vài chữ cái ựể biểu diễn các số và các kắ tự khác biểu diễn các phần tử của chuỗi sẽựược mã hoá, ta phải chọn một kắ tựựược gọi là kắ tự "Escape". Mỗi khi kắ tự ựó xuất hiện cho biết rằng hai chữ cái tiếp theo sẽ tạo thành một cặp (sốựếm, kắ tự) với các sốựếm ựược biểu diễn bằng cách dùng kắ tự thứ i của bảng chữ cái ựể biểu diễn số i. Vì vậy, chuỗi vắ dụ của chúng ta sẽựược biểu diễn như sau với Q ựược xem là các kắ tự "Escape"

QDABBBAABQHCDABCBAAAQDBCCCD

Tổ hợp của kắ tự "Escape", số ựếm và một kắ tự lặp lại ựược gọi là một dãy Escape. Chú ý rằng không ựáng ựể mã hoá các ựường chạy có chiều dài ắt

hơn bốn kắ tự, vì ắt nhất là cần ựến ba kắ tự ựể mã hoá bất kì một loạt chạy nào.

Nhưng nếu bản thân kắ tự Escape xuất hiện trong dãy nhập vào? (Vắ dụ, một ai ựó có thể thử mã hoá một chuỗi mà nó ựã ựược mã hoá rồi). Ta có thể

dùng một dãy Escape với sốựếm là 0 ựể biểu diễn kắ tự Escape. Vì vậy, trong vắ dụ trên, kắ tự khoảng trống (space) có thể biểu diễn số 0, và dãy Escape Ộ<khoảng trống>Ợ sẽ biểu diễn bất kì một sự xuất hiện nào của Q trong dãy

ựưa vào. Như vậy, nếu tập tin ựã ựược nén trước rồi bây giờ ựược nén lại lần nữa, thì nó sẽ phình ra thêm tối thiểu là một số kắ tự bằng với số dãy Escape

ựược dùng.

Các loạt chạy dài có thểựược cắt ra ựể mã hoá bằng nhiều dãy Escape, vắ dụ, một loạt chạy gồm 51 chữ A sẽ ựược mã hoá như QZAQYA bằng cách dùng trên.

Mã hoá ựộ dài loạt không có hiệu quả nhất là ựối với các tập tin văn bản do kắ tự duy nhất rất hay ựược lặp lại là khoảng trống, và có những phương pháp ựơn giản hơn ựể mã hoá các khoảng trống ựược lặp lại này. Trong các hệ

thống hiện ựại, các chuỗi khoảng trống lặp lại thì không bao giờ ựược lưu trữ: các chuỗi khoảng trống lặp lại ở nơi bắt ựầu của các dòng ựược mã hoá như

các kắ tự ỘtabỢ và các khoảng trống ở cuối của các dòng sẽ ựược tránh bằng cách dùng các dấu hiệu Ộcuối dòngỢ.

Phương pháp mã hoá ựộ dài loạt thường ựược áp dụng cho các tập tin ựồ (adsbygoogle = window.adsbygoogle || []).push({});

hoạ bitmap vì ở ựó thường có các mảng lớn cùng màu ựược biểu diễn dưới dạng bitmap là các chuỗi bit có ựường chạy dài. Trên thực tế, nó ựược dùng trong các tập tin .PCX, .RLE. [2]

Sau ựây, chúng ta sẽ xem xét tới các phương pháp tốt hơn ựể mã hoá sử

dụng phương pháp thống kê. đó là phương pháp Shano-Fano và phương pháp Huffman.

3.1.2. Mã Shanon - Fano

đây là phương pháp mã với ựộ ựài mã thay ựổi, trước khi trình bày về

phương pháp lập mã của mã Shanon - Fano, chúng tôi trình bày các khái niệm về mã ựộ dài thay ựổi.

Phương pháp nén với mã ựộ dài thay ựổi là phương pháp nén sử dụng việc mã hoá các kắ tự thành các chuỗi bit có ựộ dài khác nhau tuỳ thuộc vào tần số xuất hiện của kắ tự ựó trong file dữ liệu. Ý tưởng cơ bản của các sơ ựồ

mã hoá có chiều dài thay ựổi là dùng các mã ngắn hơn cho những kắ tự xuất hiện thường xuyên hơn. Chẳng hạn ỔEỖ ựược mã hoá trong hệ mã Morse như

là một dấu chấm duy nhất, trong khi ỔZỖ ựược biểu diễn như là - -, Ầ mục

ựắch là làm tối thiểu mã cho một kắ tự.

Vắ dụ: kắ tự A có thể mã hoá thành 01, kắ tự G có thể mã hoá là 101 Nguyên tắc cơ bản của phương pháp nén với mã ựộ dài thay ựổi là mã của kắ tự này không thể là phần ựầu của mã kắ tự khác (mã có tắnh prefix). Ta sẽ sử dụng cây nhị phân ựể xác ựịnh mã của kắ tự. Trong cây nhị phân chỉ có các lá chứa kắ tự, còn các nút khác chỉ ựể ựánh dấu ựường ựi. Trên cây nhị

phân, kắ tự nào có tần số xuất hiện lớn thì sẽ nằm gần gốc, do ựó nó có mã ngắn và ngược lại, kắ tự nào có tần số xuất hiện thấp thì sẽ nằm xa gốc và do

ựó nó có mã dài.

độc lập với nhau, Fano và Shanon ựã xây dựng phương pháp lập mã thống kê tối ưu ựều dựa trên cơ sở ựã nên ở trên: ựộ dài mã tỉ lệ nghịch với xác suất xuất hiện. độ dài mã ni ựược chọn trong phạm vi i ni

i n

m n

m− ≤ ≤ 1− , trong ựó m là cơ số mã. Thực chất hai phương pháp này là một.

3.1.2.1. Mã Shanon

Mã thống kê tối ưu Shanon ựược xây dựng theo các bước sau:

Giả sử có tập các kắ tự u={u1, u2, u3, Ầ, un} với các xác suất tương ứng pi

Bước 1: Liệt kê các kắ tự ui của tập tin và các xác suất pi theo thứ tự xác suất giảm dần.

Bước 2: Ứng với mỗi hàng ui, pi ta ghi một số Piựược tắnh như sau: Pi = p1 + p2 + Ầ + pi-1

Bước 3: đổi các số thập phân Pi ra số nhị phân (nếu dùng mã nhị phân).

Bước 4: Tắnh ni theo ựiều kiện i ni i n m n m− ≤ ≤ 1−

Từ mã tương ứng sẽ là ni kắ hiệu nhị phân kể từ phần lẻ của số nhị phân Pi

Bước 5: Kiểm tra xem ựã xét hết tất cả các tin chưa. Nếu chưa xét hết thì lặp lại bước 2.

Hình 3.1. Sơựồ gii thut to mã Shanon

Vắ dụ: Lập mã Shanon cho tập các kắ tự u sau: (adsbygoogle = window.adsbygoogle || []).push({});

u u1 u2 u3 u4 u5 u6 u7 pi 0,34 0,23 0,19 0,10 0,07 0,06 0,01 Tắnh các số Pi như sau: P1 = 0; P2 = 0,34; P3 = 0,57; P4 = 0,76; P5 = 0, 86; P6 = 0,99; P7 = 1 đổi Pi ra các số nhị phân: P1 = 0,0000; P2 = 0,0100, P3 = 0,1001; Ầ Tắnh ni theo ựiều kiện i ni i n m n m− ≤ ≤ 1− : 2-n1≤ 0,34 ≤ 21-n2, chọn n1=1,2,3,Ầ lấy n1=2 tương tự lấy n2=3; n3=3Ầ Thành lập bảng sau: Start

Bước 1 Bước 2 Bước 3 Bước 4 Bước 5

Stop False

ui pi Pi Số nhị phân Pi ni Từ mã u1 0,34 0,00 0,000 2 00 u2 0,23 0,34 0,0101 3 010 u3 0,19 0,57 0,1001 3 100 u4 0,10 0,76 0,1100 4 1100 u5 0,07 0,86 0,11011 4 1101 u6 0,06 0,93 0,11101 5 11101 u7 0,01 0,99 0,1111110 7 1111110

Bng 3.1. Lp các t mã Shanon cho tp kắ t u={u1, u2, Ầ, un}.

độ dài mã trung bình: ∑ = = = n i i ip u n n 1 ) ( 0,01*7 + 0,06*5 + 0,07*4 + 0,10*4 + 0,19*3 + 0,23*3 +0,34*2 = 2,99 (bit/ kắ tự). 3.1.2.2. Mã Fano

Mã thống kê tối ưu Fano ựược xây dựng bằng cách duyệt một cây nhị

phân. Cây nhị phân này ựược xây dựng như sau: từ bảng tần số xuất hiện của các kắ tự có trong dữ liệu cần nén, ta thực hiện các bước như sau:

Bước 1: Sắp xếp các kắ tự ui theo thứ tự pi giảm dần (hoặc tăng dần).

Bước 2: Chia làm hai nhóm có tổng xác suất gần bằng nhau (tức là tìm vị

trắ của ui nào ựó trong bảng tần số sao cho tổng tần số của tất cả các kắ tự (tắnh cả kắ tựựó) bằng hoặc gần bằng tổng số tổng số xuất hiện của các kắ tự trong bảng tần số tắnh từ kắ tựựứng kế tiếp.

Bước 3: Tạo một cây nhị phân có nút cha nhận tần số xuất hiện là tổng số

tần số của cả bảng, cây con trái lấy kắ hiệu 0, con phải lấy kắ hiệu 1.

Bước 4: Thực hiện lại việc chia ựôi và kắ hiệu như vậy ựối với các cây con trái và cây con phải cho ựến khi không thể phân chia ựược nữa.

Sau bước này, ta ựược một cây nhị phân.

Hình 3.2. Sơựồ gii thut to mã Fano

Vắ d: Cho nguồn gồm 7 kắ tự u1, Ầ, u7 có xác suất xuất hiện lần lượt là: 0,34; 0,23; 0,19; 0,10; 0,07; 0,06; 0,01. Mã Fano ựược xây dựng theo cây như

sau:

Hình 3.3. Cây mã Fano cho tp kắ t u = {u1, u2, Ầ, u7}

Có thể thấy rằng trong trường hợp này cây nhị phân Fano là cây nhị phân suy biến.

Sau khi có cây nhị phân thì ta lập bảng mã Fano, bảng này gồm ba thành phần chắnh là tên kắ tự, chiều dài ựoạn mã và ựoạn mã, việc xác ựịnh ựường ựi tới nút con trái ứng với 0 và con phải ứng với 1 chỉ là quy ước, ta có thể thay

ựổi lại sự tương ứng trái - 0 và phải -1 thành trái - 1 và phải - 0 mà không gây ra sai sót nào.

Start

Bước 1 Bước 2 Bước 3 Bước 4 Bước 5

Stop False True 0 0 0 0 0 0 1 1 1 1 1 00 01 10 110 1110 1111 1111 0,57 0,34 0,23 0,19 0,43 0,24 0,10 0,14 0,07 0,07 0,06

ui Từ mã Chiều dài từ mã u1 00 2 u2 01 2 u3 10 2 u4 110 3 u5 1110 4 u6 11110 5 u7 11111 5 Bng 3.2. Bng mã Fano ca tp kắ t u = {u1, u2, Ầ, u7} Nhn xét:

- để nén một tệp dữ liệu bằng phương pháp Fano - Shanon, công việc

ựầu tiên là phải ựọc tệp nguồn ựể thống kê tần số xuất hiện của mỗi kắ hiệu. Sau khi thống kê xong, người ta sắp xếp bảng tần số theo thứ tự giảm dần của tần số xuất hiện.

- Bảng mã tương ứng của các kắ hiệu ựược gửi tới cho chương trình giải nén như sau: mỗi kắ hiệu dùng 3 byte, byte thứ nhất mang kắ tựựể chuyển mã, 4 bit tiếp theo (4 bit ựầu của byte thứ hai) mang ựộ dài của mã, phần còn lại mang mã tối ựa của kắ hiệu. Trong quá trình giải nén phải sử dụng bảng mã nhận ựược từ thuật toán nén, ựồng thời ựể giải mã cần phải dựa vào nhận xét: không một mã nào là phần ựầu của mã khác. (adsbygoogle = window.adsbygoogle || []).push({});

- Hai phương pháp mã Fano và Shanon thực chất là một, tuy nhiên hai phương pháp này không cho phép lập mã một cách duy nhất vì sự chia nhóm dựa trên cơ sởựồng ựều và tổng xác xuất nên có thể có nhiều cách chia.

- Sự lập mã của cả hai phương pháp theo cách chia nhóm trên cơ sởựồng xác xuất tạo cho bộ mã có tắnh prefix.

3.1.3. Mã Huffman

đây là một trong những phương pháp nén tốt nhất dựa vào những thống kê xác xuất, phương pháp này ựã ựược D. A. Huffman ựưa ra năm 1952 bằng cách tạo một bảng mã cho một tập các kắ tự bằng cách dựa vào xác suất của

chúng trong văn bản. Mã Huffman là một mã có tắnh prefix có ựộ dài từ mã tối thiểu. Mã này thoả mãn 3 tắnh chất sau:

- Tắnh cht 1: Tắnh th t ca ựộ dài t: nếu sắp xếp tin theo thứ tự

xác suất giảm dần pi ≥ pj với i < j thì ựộ dài các từ mã tương ứng phải thoả

nãm ựiều kiện ni≤ nj.

- Tắnh cht 2: Tắnhcht ca nhng t mã cui: bất kì trường hợp nào hai từ mã cuối (số từ mã không nhiều hơn cơ số m của mã) có ựộ dài bằng nhau, về trọng lượng chỉ khác nhau ở trọng lượng kắ hiệu cuối). Có n0 từ mã cuối với n0 thoả mãn ựiều kiện 2≤ n0 ≤m.

- Tắnh cht 3: Tắnh liên h nhng t mã cui và nhng t mã trước cui: một dãy bất kì gồm n kắ hiệu mã thì phải là một từ mã hoặc là prefix của các từ mã cuối.

3.1.3.1. Thut toán lp mã Huffman

Mã Huffman ựược xây dựng theo thuật toán sau: [3]

Bước 1: Sắp xếp các kắ tự có trong tập tin theo thứ tự xác suất tăng dần (hoặc giảm dần).

Bước 2: Tắnh no (số từ mã cuối) theo ựiều kiện: n0 là số nguyên thoả

mãn:     − − ≤ ≤ 1 2 0 0 m n N m n là số nguyên lớn nhất.

Trong trường hợp mã nhị phân thì n0 = 2.

Bước 3: Tiến hành xây dựng cây mã và duyệt cây ựể tìm các từ mã. Vấn ựề then chốt ở ựây là làm thế nào ựể tạo cây mã? Giả thiết ban ựầu có các nút lá, mỗi nút lá tượng trưng cho một kắ tự và trọng lượng của nút lá chắnh là xác suất của kắ tự tương ứng.

Huffman ựã ựưa ra thuật toán sau ựể thực hiện tạo cây nhị phân lập mã

Một phần của tài liệu MÃ HOÁ NÉN DỮ LIỆU VÀ MÃ HOÁ CÓ KHẢ NĂNG PHÁT HIỆN SAI VÀ SỬA SAI (Trang 33 - 96)