Vì vậy, tôi ñã chọn nghiên c ứu ñề tài: “Mã hoá nén dữ liệu và mã hoá có khả năng phát hiện sai và sửa sai” với mục ñích tìm hiểu các thuật toán ñó và cài ñặt một số thuật toán b ằng
Trang 1ðẠI HỌC THÁI NGUYÊN TRƯỜNG ðẠI HỌC SƯ PHẠM
KHOA TOÁN
- -
MÃ HOÁ NÉN DỮ LIỆU VÀ
MÃ HOÁ CÓ KHẢ NĂNG PHÁT HIỆN
SAI VÀ SỬA SAI
LUẬN VĂN TỐT NGHIỆP ðẠI HỌC
THÁI NGUYÊN
Trang 2ðẠI HỌC THÁI NGUYÊN TRƯỜNG ðẠI HỌC SƯ PHẠM
KHOA TOÁN
- -
LÊ QUÝ TÀI
MÃ HOÁ NÉN DỮ LIỆU VÀ
MÃ HOÁ CÓ KHẢ NĂNG PHÁT HIỆN
SAI VÀ SỬA SAI
Chuyên ngành: Tin học LUẬN VĂN TỐT NGHIỆP ðẠI HỌC
Người hướng dẫn khoa học: Thạc sỹ Nguyễn Văn Trường
Trang 3LỜI NÓI ðẦU
Máy tính ra ñời giúp con người lưu trữ và xử lý thông tin, bên cạnh việc
x ử lý nhanh, người ta còn quan tâm ñến việc lưu trữ ñược nhiều thông tin
nh ưng lại tiết kiệm ñược bộ nhớ và giảm chi phí lưu trữ Mặt khác, khi mạng
máy tính ra ñời, nhu cầu trao ñổi thông tin lại càng lớn hơn, dẫn ñến nhu cầu
ph ải giảm thiểu thời gian và chi phí ñể trao ñổi dữ liệu trên mạng Khi truyền
tin, có th ể vì một lí do nào ñó mà tập tin bị lỗi, một câu hỏi ñặt ra là có thể
khôi ph ục lại tập tin ban ñầu từ tập tin lỗi ñó hay không?
T ất cả những vấn ñề trên nảy sinh ra khái niệm nén dữ liệu, nén dữ liệu
nh ằm tiết kiệm không gian lưu trữ cũng như tăng hiệu suất truyền tin, ñồng
th ời ñây cũng là một phương pháp ñể bảo mật dữ liệu Cùng với nén dữ liệu
thì mã hoá có kh ả năng phát hiện sai và sửa sai cũng phát triển mạnh bởi ñây là phương pháp mã hoá giúp tăng ñộ tin cậy của dữ liệu khi truyền ñi
trên m ạng
ðể giải quyết những yêu cầu ñó, cách ñây khoảng nửa thế kỉ, nhiều nhà
khoa h ọc ñã phát minh ra những thuật toán ñể phục vụ cho việc nén dữ liệu
c ũng như phát hiện và sửa sai ðến nay, những thuật toán ñó ñã ñược cải tiến,
t ối ưu, ñồng thời nhiều thuật toán mới cũng ra ñời Vì vậy, tôi ñã chọn nghiên
c ứu ñề tài: “Mã hoá nén dữ liệu và mã hoá có khả năng phát hiện sai và
sửa sai” với mục ñích tìm hiểu các thuật toán ñó và cài ñặt một số thuật toán
b ằng ngôn ngữ lập trình cụ thể nhằm làm sáng rõ và cải tiến thuật toán
Trong th ời gian làm ñề tài, tôi ñã nhận ñược sự giúp ñỡ, chỉ dẫn của
Th ạc sỹ Nguyễn Văn Trường ðồng thời tôi cũng nhận ñược những ý kiến ñóng góp của các bạn ñồng nghiệp Vì thời gian làm ñề tài có hạn nên chắc
ch ắn không tránh khỏi những thiếu sót, rất mong nhận ñược những góp ý của
các quý th ầy cô và các bạn ñể ñề tài chất lượng và thiết thực hơn
Tôi xin chân thành c ảm ơn!
Sinh viên
Lê Quý Tài
Trang 4
MỤC LỤC
LỜI NÓI ðẦU 2
MỤC LỤC 3
MỞ ðẦU 5
1 Lí do chọn ñề tài 5
2 Lịch sử nghiên cứu ñề tài 5
3 Mục ñích nghiên cứu ñề tài 6
4 Giới hạn của ñề tài 6
5 Phương pháp nghiên cứu 7
6 Cấu trúc của ñề tài 7
Chương 1 NHỮNG KIẾN THỨC LIÊN QUAN 8
1.1 Cấu trúc dữ liệu cây 8
1.1.1 ðịnh nghĩa và các khái niệm 8
1.1.2 Cây nhị phân 9
1.2 Cấu trúc dữ liệu kiểu con trỏ 12
1.2.1 Khái niệm 12
1.2.2 Sử dụng con trỏ xây dựng cây nhị phân 15
1.3 Vài nét về ngôn ngữ lập trình C và C++ 17
1.4 Vài nét về ngôn ngữ lập trình Visual Basic 19
Chương 2 CÁC KHÁI NIỆM CƠ BẢN 21
2.1 ðịnh nghĩa và các khái niệm về mã hoá 21
2.1.1 ðịnh nghĩa 21
2.1.2 Một số khái niệm cơ bản về mã hoá 22
2.1.3 Các phương pháp biểu diễn mã 23
2.1.4 ðiều kiện ñể mã phân tách ñược và mã có tính Prefix 26
2.2 Mã hoá nén dữ liệu 27
2.2.1 Khái niệm 27
Trang 5
2.2.2 Tầm quan trọng của việc nén dữ liệu 28
2.2.3 Phân loại 29
2.2.4 Giới thiệu một số chuẩn nén 30
2.3 Mã hoá có khả năng phát hiện sai và sửa sai 31
2.3.1 Khái niệm 31
2.3.2 Tầm quan trọng của việc mã hoá sửa sai 31
Chương 3 THUẬT TOÁN NÉN DỮ LIỆU 32
3.1 Các thuật toán nén dữ liệu theo kiểu thống kê 32
3.1.1 Phương pháp mã hoá ñộ dài loạt 32
3.1.2 Mã Shanon - Fano 34
3.1.3 Mã Huffman 39
3.1.4 Mã số học 50
3.2 Các thuật toán nén dữ liệu theo kiểu từ ñiển 54
3.2.2 Thuật toán LZ77 - LZ78 55
3.2.3 Thuật toán LZW 61
Chương 4 MÃ PHÁT HIỆN SAI VÀ SỬA SAI 74
4.1 Mã Hamming 74
4.2 Mã CRC 82
KẾT LUẬN 89
TÀI LIỆU THAM KHẢO 91
PHỤ LỤC 93
Trang 6có phương pháp nén dữ liệu ñể nâng cao chất lượng, tốc ñộ truyền tin và giảm thiểu chi phí
Trong quá trình truyền tải dữ liệu, có thể vì một lí do nào ñó mà tập dữ liệu bị hỏng, ñòi hỏi cần có phương pháp giúp khôi phục lại tập tin ban ñầu từ tập tin bị hỏng
Nhiều thuật toán nén dữ liệu ñã ñược phát minh, phát triển và tối ưu qua nhiều năm và ñược ứng dụng trong nhiều sản phẩm phần mềm có giá trị phục
vụ cho người dùng máy tính Việc tìm hiểu, cài ñặt và tối ưu các thuật toán ñó
là một yêu cầu cấp thiết ñang ñặt ra Vì vậy, tôi ñã mạnh dạn chọn nghiên cứu
ñề tài “Mã hoá nén dữ liệu và mã hoá có khả năng phát hiện sai và sửa
sai” Trên cơ sở ñề tài này, tôi sẽ nghiên cứu và phát triển phần mềm nén dữ liệu với khả năng nén cao và hiệu quả
2 Lịch sử nghiên cứu ñề tài
Những nền tảng ban ñầu của lĩnh vực nén dữ liệu ñã xuất hiện vào những năm 1940 cùng với sự phát triển của lí thuyết thông tin Những khái niệm ban ñầu ñã ñược ñưa ra cuối những năm 1940 bởi Claude Shanon tại phòng thí nghiệm Bell Nén dữ liệu liên quan ñến hàng loạt vấn ñề thông tin, bao gồm việc lưu trữ và truyền thông tin
Các nhà nghiên cứu ñã ñưa ra các phương pháp khác nhau ñể nén dữ liệu, trong ñó hai thuật toán mã Huffman và mã Shanon - Fano ñược công bố khá sớm Thuật toán mã Huffman ñược David A Huffman ñưa ra năm 1952
và ñược chấp nhận rộng rãi và luôn ñược sử dụng cho các chương trình nén
Trang 7
dữ liệu trước năm 1980, còn thuật toán mã Shanon - Fano do Claude Shanon công bố Do tính ñơn giản, dễ xây dựng, không quá tốn thời gian của CPU nên vẫn ñược sử dụng rộng rãi
ðến năm 1980, hầu hết các phương pháp nén ñều sử dụng phương pháp thống kê Nhưng vào năm 1977 - 1978, Jacov Ziv và Abraham Lempel ñã mô
tả một cặp phương pháp nén sử dụng kết hợp từ ñiển, ñã ñạt ñược một tỉ lệ nén ñầy ấn tượng ðến năm 1984, Terry Welch’s ñã phát triển thuật toán LZ78 và ñưa ra giới thiệu thuật toán nén dữ liệu LZW (Lempel-Ziv-Welch)
Mã Hamming ñược R W Hamming ñưa ra và ñược dùng trong một số
hệ thống sử dụng kĩ thuật Forward Error Correction (FEC), mã này có khả năng sửa sai một lỗi, mã Hamming ñược sử dụng khá rộng rãi trong thực tế Ngoài ra, còn rất nhiều phương pháp khác ñể nén dữ liệu cũng như ñể kiểm tra và sửa lỗi: phương pháp của Meggit, Kasamin, Mitchell và Rudolph, giải thuật của Berlekamp…
3 Mục ñích nghiên cứu ñề tài
Với ñề tài “Mã hoá nén dữ liệu và mã hoá có khả năng phát hiện sai và sửa sai”, chúng tôi có mục ñích nghiên cứu:
- Khái niệm tổng quan về mã hoá và mã hoá nén dữ liệu, mã hoá có khả năng phát hiện sai và sửa sai
- Tìm hiểu các thuật toán nén dữ liệu và cài ñặt bằng ngôn ngữ lập trình một số thuật toán nén dữ liệu tiêu tiểu
- Tìm hiểu về phương pháp mã hoá có khả năng phát hiện sai và sửa sai
và cài ñặt mô phỏng bằng ngôn ngữ lập trình
Tuy nhiên, do khái niệm mã hoá nói chung cũng như mã hoá nén dữ liệu
và mã hoá có khả năng phát hiện sai và sửa sai khá rộng và phức tạp, do ñó, với khuôn khổ của một luận văn tốt nghiệp, chúng tôi chỉ giới hạn nghiên cứu những nội dung dưới ñây
4 Giới hạn của ñề tài
- Nghiên cứu những nét tổng quan về mã hoá nói chung, mã hoá nén dữ liệu và mã hoá có khả năng phát hiện sai và sửa sai
Trang 8
- Tiến hành cài ñặt bằng ngôn ngữ lập trình một số thuật toán nén dữ liệu
và mã hoá sửa sai tiêu biểu, các thuật toán khác chỉ ñược trình bày những nét khái quát và không có chương trình cài ñặt cụ thể
5 Phương pháp nghiên cứu
Với những nội dung giới hạn trên ñây và dựa vào những yêu cầu của ñề tài và tình hình thực tế, chúng tôi ñã chọn những phương pháp nghiên cứu sau:
- Phương pháp nghiên cứu tài liệu
- Phương pháp tổng hợp, khái quát hoá
- Phương pháp thực nghiệm
6 Cấu trúc của ñề tài
Căn cứ theo mục ñích nghiên cứu cũng như giới hạn của ñề tài, chúng tôi chia ñề tài làm 4 chương, với các nội dung chủ yếu của mỗi chương như sau:
Chương 1 Những kiến thức liên quan: Trình bày những kiến thức có liên quan có sử dụng khi viết chương trình như: cấu trúc dữ liệu ñộng, cấu trúc dữ liệu kiểu con trỏ, cấu trúc dữ liệu cây…, và một vài nét về các ngôn ngữ lập trình ñược sử dụng ñể viết chương trình (C++, Visual Basic)
Chương 2 Các khái niệm cơ bản: Trình bày các ñịnh nghĩa và khái niệm cơ bản về mã hoá, mã hoá nén dữ liệu và mã hoá có khả năng phát hiện sai và sửa sai
Chương 3 Thuật toán nén dữ liệu: Trình bày các thuật toán nén dữ liệu ñược phân loại theo phương pháp nén, ñồng thời trình bày chi tiết về chương trình cài ñặt minh hoạ
Chương 4 Mã phát hiện sai và sửa sai: Trình bày các phương pháp mã hoá có khả năng phát hiện sai và sửa sai cùng với mô tả chi tiết việc cài ñặt minh hoạ của thuật toán
Trang 9
Chương 1 NHỮNG KIẾN THỨC LIÊN QUAN
Chương này trình bày những kiến thức liên quan có sử dụng khi cài ñặt các thuật toán nén dữ liệu và mã hoá sửa sai ðây là các kiến thức cơ sở giúp xây dựng chương trình, vì vậy, chúng tôi sẽ chú ý ñến việc thể hiện của các kiến thức này trên ngôn ngữ lập trình (cụ thể là ngôn ngữ lập trình C)
1.1 Cấu trúc dữ liệu cây
1.1.1 ðịnh nghĩa và các khái niệm
Một cây (tree) là một tập hợp hữu hạn các nút trong ñó có một nút dặc biệt ñược gọi là gốc (root), giữa các nút có quan hệ phân cấp gọi là quan hệ
“cha-con”
ðịnh nghĩa cây một cách ñệ quy:
1 Một nút là một cây, nút ñó cũng là gốc của cây ấy
2 Nếu T1, T2, …, Tk là các cây, với n1, n2, …, nk lần lượt là các gốc n là một nút và n có quan hệ cha con với n1, n2, …, nk thì lúc ñó một cây mới T sẽ ñược tạo lập, với n là gốc của nó, n ñược gọi là cha của n1, n2, …, nk; ngược lại n1, n2, …, nk ñược gọi là con của n Các cây T1, T2, …, Tk ñược gọi là các
cây con (subtrees) của n [6]
Quy ước: một cây không có nút nào ñược gọi là cây rỗng (null tree)
Chẳng hạn, hình 1.1 dưới ñây biểu diễn một cây:
Hình 1.1 M ột cây
A
Trang 10
Số các con của một nút gọi là cấp (degree) của nút ñó Ví dụ, cấp của A
là 3, cấp của H là 2
Nút có cấp bằng không gọi là lá (leaf) hay nút tận cùng (terminal node),
ví dụ các nút E, C, K,… nút không có lá ñược gọi là nút nhánh (branch node)
Cấp cao nhất của nút trên cây gọi là cấp của cây ñó Ví dụ, cây hình 1.1
là cây cấp 3
Gốc của cây có số mức (level) là 1 Nếu nút cha có số mức là i thì nút
con có số mức là i+1 Ví dụ A có mức 1, D có mức 2
Chiều cao (heigh) hay chiều sâu (depth) của một cây là số mức lớn nhất
của nút ñó có trên cây ñó Ví dụ, cây hình 1.1 có chiều cao 4
Nếu n1, n2, …, nk là dãy nút mà ni là cha của ni+1 với 1 ≤ i < k, thì dãy ñó gọi là ñường ñi (path) từ n1 tới nk Ví dụ, trong hình 1.1 ñộ dài ñường ñi từ A ñến K là 3
Nếu thứ tự các cây con của một nút ñược coi trọng thì cây ñang xét là
cây thứ tự (ordered tree), ngược lại là cây không có thứ tự (unordered tree)
Thường thứ tự các cây con của một nút ñược ñặt từ trái sang phải
Nếu một tập hữu hạn các cây phận biệt thì ta gọi ñó là rừng (forest)
1.1.2 Cây nhị phân
1.1.2.1 ðịnh nghĩa
Cây nhị phân là một cây mà mỗi nút trên cây chỉ có tối ña hai con
ðối với cây nhị phân người ta cũng phân biệt cây con trái (left subtree)
và cây con phải (right subtree) Như vậy, cây nhị phân là cây có thứ tự
Cây nhị phân hoàn chỉnh (complete binary tree) là cây nhị phân mà các nút ứng với các mức trừ mức cuối cùng ñều ñạt tối ña và ở mức cuối các nút ñều dạt về phía trái Cây nhị phân ñầy ñủ (full binary tree) là cây nhị phân mà các nút tối ña ở mọi mức Cây gần ñầy là cây nhị phân mà các nút ứng với các mức trừ mức cuối cùng ñều ñạt tối ña.[6]
Trang 11b) Lưu trữ móc nối
Trong cách lưu trữ này, mỗi nút ứng với một phần tử nhớ có quy cách như sau:
- Trường INFO ứng với thông tin (dữ liệu) của nút
- Trường LPTR ứng với con trỏ, trỏ tới cây con trái của nút ñó
- Trường RPTR ứng với con trỏ, trỏ tới cây con phải của nút ñó
ðể có thể truy cập vào các nút cây cần có một con trỏ T, trỏ tới nút gốc của cây ñó
Ví dụ: Hình 1.2 mô tả một cây nhị phân và hình 1.3 là biểu diễn cây nhị phân ñó dưới dạng lưu trữ móc nối:
Trang 12
Hình 1.3 M ột cây nhị phân ñược dưới dạng lưu trữ móc nối
Quy ước: Nếu cây nhị phân rỗng thì T=null
Với cách biểu diễn này từ nút cha có thể truy cập trực tiếp vào nút con, nhưng ngược lại thì không làm ñược
1.1.2.3 Duyệt cây nhị phân
Phép xử lý các nút trên cây - phép toán thăm (visit) các nút - một cách hệ
thống, sao cho mỗi nút chỉ ñược thăm một lần, gọi là phép duyệt cây
Các phép duyệt cây ñược ñịnh nghĩa một cách ñệ quy như sau:
a) Duyệt cây theo thứ tự trước (preorder traversal)
1) Nếu cây rỗng thì không làm gì
2) Nếu cây không rỗng thì:
- Thăm gốc;
- Duyệt cây con trái theo thứ tự trước;
- Duyệt cây con phải theo thứ tự trước
Ví dụ: thứ tự duyệt cây ở hình 1.2: A B D E C F G H I
b) Duyệt cây theo thứ tự giữa (inorder traversal)
1) Nếu cây rỗng thì không làm gì
2) Nếu cây không rỗng thì:
- Duyệt cây con trái theo thứ tự giữa;
Trang 13
- Thăm gốc;
- Duyệt cây con phải theo thứ tự giữa
Ví dụ: thứ tự duyệt cây ở hình 1.2: D B E A F C H G I
c) Duyệt theo thứ tự sau (postorder traversal)
1) Nếu cây rỗng thì không làm gì
2) Nếu cây không rỗng thì:
- Duyệt cây con trái theo thứ tự sau;
- Duyệt cây con phải theo thứ tự sau;
- Thăm gốc
Ví dụ: thứ tự duyệt cây ở hình 1.2: D E B F H I G C A
1.2 Cấu trúc dữ liệu kiểu con trỏ
Trong phần này, chúng tôi sẽ trình bày khái niệm, cách sử dụng và ứng dụng của kiểu dữ liệu con trỏ trong ngôn ngữ lập trình C (ngôn ngữ lập trình ñược dùng chính ñể cài ñặt các thuật toán)
1.2.1 Khái niệm
Khi khai báo một biến, chẳng hạn int i=10; hệ thống sẽ cấp phát một vùng nhớ gồm 2 byte liên tiếp cho biến i ðịa chỉ của biến là chỉ số của byte ñầu tiên trong dãy các byte liên tiếp mà hệ thống dành cho biến Như vậy, một biến sẽ có 3 ñặc trưng: ñịa chỉ của biến, số byte lưu trữ, giá trị hiện thời Từ ñịa chỉ của biến, chúng ta có thể duyệt ñược tất cả các ñịa chỉ của byte nằm trong dãy byte biểu diễn
Một giá trị con trỏ là một hằng ñịa chỉ của một biến hoặc một hàm Ví
dụ: int i; &i là một hằng con trỏ
Kiểu dữ liệu con trỏ phụ thuộc vào kiểu của biến mà nó trỏ tới Ví dụ:
int i; &i là một hằng con trỏ, kiểu int * Có bao nhiêu kiểu dữ liệu thì cũng có bấy nhiêu kiểu dữ liệu con trỏ tương ứng
Một biến con trỏ là biến với kiểu giá trị con trỏ
Dạng chung ñể khai báo biến con trỏ:
Trang 14
tên_kiểu_dữ_liệu *tên _biến_con_trỏ;
Ví d ụ:
int *pi; //Khai báo biến pi là biến kiểu con trỏ int
int i; //khai báo biến int
pi=&i; //biến pi có giá trị hiện thời là ñịa chỉ của biến i
Cấp phát ñộng
Các biến mảng, xâu khi ñược khai báo tổng thể sẽ tồn tại trong bộ nhớ cho tới khi ứng dụng kết thúc Việc chiếm dụng tài nguyên bộ nhớ có thể dẫn tới bộ nhớ không còn cho các tác vụ khác trong một ứng dụng phức tạp Do
ñó, C có cơ chế giúp các biến có thể ñược tạo ra lúc chạy chương trình, tuỳ theo nhu cầu, do vậy mà số biến này hoàn toàn không ñược xác ñịnh từ trước Việc tạo ra biến ñộng và xoá ñi nó (ñể thu hồi bộ nhớ) ñược thực hiện nhờ các hàm như malloc() và free() khai báo sẵn trong thư viện stdlib.h Việc
truy nhập các biến ñộng ñược thực hiện thông qua các biến con trỏ (Pointer
Variable) Các biến con trỏ ñược ñịnh nghĩa như là biến tĩnh (nghĩa là có tên
và ñược khai báo ngay từ ñầu trong phần khai báo biến) và ñược dùng ñể chứa ñịa chỉ của các biến ñộng
Hàm cấp phát ñộng cơ bản: khai báo trong thư viện stdlib.h
(datatype *)malloc(unsigned int size);
Hàm malloc xin cấp phát size byte từ bộ nhớ chính cho một ñối tượng, trả về con trỏ trỏ tới vùng nhớ mới ñược cấp phát hoặc NULL nếu không cấp phát ñược vùng nhớ Mẫu (datatype *) chính là kiểu con trỏ và ñược hiểu
là chuyển ñổi thành kiểu con trỏ trỏ tới datatype
void free(void *block); Hàm này trả lại hệ thống phần bộ nhớ ñã xin cấp phát từ hàm malloc
(datatype *)realloc(buf_ptr, newsize); Hàm cấp phát lại
bộ nhớ trước ñó Trong ñó: buf_ptr là con trỏ ñang trỏ tới vùng ô nhớ ñã ñược cấp phát từ trước, newsize là kích thước mới cần cấp phát, có thể to hơn hoặc nhỏ hơn
Trang 15
Trong ngôn ngữ C ++ :
C++ ñã tích hợp hai toán tử new và delete ñể thực hiện việc cấp phát ñộng cho các biến
Toán tử new và new[ ]
ðể có thể có ñược bộ nhớ ñộng chúng ta có thể dùng toán tử new Theo sau toán tử này là tên kiểu dữ liệu và có thể là số phần tử cần thiết ñược ñặt trong cặp ngoặc vuông Nó trả về một con trỏ trỏ tới ñầu của khối nhớ vừa ñược cấp phát Dạng thức của toán tử này như sau:
pointer = new type
hoặc
pointer = new type [elements]
Biểu thức ñầu tiên ñược dùng ñể cấp phát bộ nhớ chứa một phần tử có kiểu type Lệnh thứ hai ñược dùng ñể cấp phát một khối nhớ (một mảng) gồm các phần tử kiểu type
Ví d ụ: int * bobby;
bobby = new int [5];
Trong trường hợp này, hệ ñiều hành dành chỗ cho 5 phần tử kiểu int
trong bộ nhớ và trả về một con trỏ trỏ ñến ñầu của khối nhớ Vì vậy lúc này
bobby trỏ ñến một khối nhớ hợp lệ gồm 5 phần tử int
Bộ nhớ ñộng nói chung ñược quản lí bởi hệ ñiều hành và trong các môi trường ña nhiệm có thể chạy một lúc vài chương trình có một khả năng có thể xảy ra là hết bộ nhớ ñể cấp phát Nếu ñiều này xảy ra và hệ ñiều hành không thể cấp phát bộ nhớ như chúng ta yêu cầu với toán tử new, một con trỏ null
(zero) sẽ ñược trả về Vì vậy nên kiểm tra xem con trỏ trả về bởi toán tử new
có bằng null hay không:
Trang 16Gán con tr ỏ hàm: chúng ta phải gán giá trị của nó bằng ñịa chỉ ñiểm vào
của một hàm thực sự, cách gán: Tên_biến_con_trỏ_hàm = Tên_hàm;
1.2.2 Sử dụng con trỏ xây dựng cây nhị phân
Một ứng dụng khác của con trỏ và biến ñộng là xây dựng cấu trúc dữ liệu kiểu cây nhị phân Chẳng hạn, ta cần xây dựng một cây nhị phân chứa các số nguyên Cây gồm các nút chứa các giá trị (số nguyên), mỗi nút có hai nhánh
Số ñầu tiên ñược ñặt vào một nút gọi là nút gốc Sau ñó số nguyên ñưa vào tiếp ñược so sánh với các nút kể từ nút gốc Nếu lớn hơn hoặc bằng số nguyên của nút vừa ñặt vào thì nó ñược rẽ sang nhánh bên phải của nút ấy, nếu bé hơn thì rẽ sang nhánh bên trái
Như vậy, ta thấy cách khai báo này rất giống với khai báo danh sách móc
nối hai chiều: mỗi nút chứa hai con trỏ, con trỏ left dùng ñể trỏ tới cây con
Trang 17Trong ñó Dat_so(p,Root) là hàm ñặt thêm số p vào cây có gốc Root
void Dat_so(struct Phan_tu *n1, struct Phan_tu *n2) {
Trang 18có các tính ưu việt và tính mềm dẻo nên nó ñã ñược giới tin học nhanh chóng chấp nhận như là một ngôn ngữ chính thống nhà nghề
ðến năm 1978, bản in ñầu tiên về ngôn ngữ C ñã ñược in ra thành sách
“The C programming language” do Kernighan và Ritchie viết C mau chóng
ñược Viện tiêu chuẩn hoá của Mĩ (ANSI: American National Standard
Institute) làm thành tiêu chuẩn với tên gọi “ANSI C” vào năm 1983 Tổ chức
tiêu chuẩn hoá quốc tế ISO (International Standard Organization) cũng xây
dựng chuẩn cho C May mắn thay cho người dùng là các chuẩn này giống nhau và ñược biết ñến với cái tên chung là ANSI C
C là một ngôn ngữ mạnh và mềm dẻo ðiều hạn chế ñối với C chính là
óc tưởng tượng của người lập trình C không ñặt ñiều kiện ràng buộc nào cho người sử dụng C ñược dùng ñể viết hệ ñiều hành, các trình ñiều khiển, soạn thảo văn bản, ñồ hoạ, bảng tính… và thậm chí là các chương trình dịnh cho các ngôn ngữ khác
C là ngôn ngữ ñược các nhà tin học chuyên nghiệp dùng phổ biến, nhất
là trong việc viết phần mềm hệ thống (hệ ñiều hành, chương trình dịch, soạn thảo văn bản, cơ sở dữ liệu, bảng tính…) Trong các hệ ñiều hành nổi tiếng như UNIX, Linux hay Windows thì phần lớn các modul ñều ñược viết bằng ngôn ngữ C Một trong các lí do này là tính hiệu quả của chương trình ñược dịch ra Một chương trình C khi dịch ra có thể ñạt 80% tính năng của chương trình ñó viết bằng mã máy Có khá nhiều chương trình dịch và các thư viện tiện ích khác cho C có thể khai thác ñược
C là ngôn ngữ có thể chuyển dịch (portable) hay còn gọi là tính dễ thích
nghi Tính dễ thích nghi hay tính di chuyển ñược hiểu là chương trình C viết chi máy tính IBM có thể ñem sang hệ thống máy khác như VAX của công ty
Trang 19C là một ngôn ngữ có tắnh modul đó chắnh là việc sử dụng các chương
trình con loại hàm (function) Các hàm này có thể sử dụng nhiều lần trong
chương trình hoặc trong chương trình khác Tuy nhiên, C không cho phép khai báo hàm trong hàm
C là ngôn ngữ bậc trung So với ngôn ngữ bậc cao, một ngôn ngữ bậc trung không có nghĩa là xấu, là tồi Bậc trung có nghĩa là khó dùng hơn và ắt ựược phát triển một cách hoàn thiện cho người dùng hơn C ựược gọi là bậc trung là vì nó kết hợp ựược các tắnh năng của ngôn ngữ bậc cao với ngôn ngữ bậc thấp
Các ngôn ngữ bậc cao có các kiểu dữ liệu rất dễ dùng C có 5 kiểu dữ liệu cơ sở Nếu xét về phương diện kiểu dữ liệu thì C không ựược mạnh như Pascal nên cũng khó dùng Vắ dụ, việc trộn lẫn kiểu số nguyên với kiểu kắ tự làm nhiều cho người lúng túng
C là ngôn ngữ bậc trung nên nó rất mạnh về mặt xử lắ bit, byte và xử lắ ựịa chỉ ô nhớ Vì vậy, C rất thắch hợp cho lập trình hệ thống
đầu những năm 1980, một tư tưởng lập trình mới ựược ựưa ra dựa trên việc tổ chức chương trình thành các lớp, phương pháp này ựã thay ựổi hẳn phương pháp lập trình cấu trúc truyền thống, ựó chắnh là lập trình hướng ựối tượng Các ngôn ngữ lập trình cũng ựược thiết kế lại ựể ựáp ứng ựược phương pháp lập trình mới để ựưa C vào thế giới hướng ựối tượng, năm 1980 Bjanre Stroustrup ựã cho ra ựời một ngôn ngữ C mới có tên ban ựầu là ỘC có lớp, sau
ựó ựến năm 1983 thì gọi là C++ Ngôn ngữ C++ là một sự phát triển mạnh mẽ của C C++ chẳng những ựưa tất cả các khái niệm, công cụ của lập trình hướng ựối tượng mà còn ựưa vào nhiều khả năng mới mẻ cho hàm Như vậy, C++ là một ngôn ngữ lai cho phép tổ chức chương trình theo các lớp và các hàm Có thể nói, C++ ựã thúc ựẩy ngôn ngữ C vốn ựã rất thuyết phục ựi vào thế giới lập trình hướng ựối tượng và C++ ựã trở thành ngôn ngữ hướng ựối tượng nổi bật trong những năm 90
Trang 20
1.4 Vài nét về ngôn ngữ lập trình Visual Basic
Visual Basic là gì? Phần "Visual" ñề cập ñến phương pháp ñược sử dụng
ñể tạo giao diện ñồ họa người dùng (Graphical User Interface - GUI) Có sẵn
những bộ phận hình ảnh, gọi là controls, bạn tha hồ sắp ñặt vị trí và quyết
ñịnh các thuộc tính của chúng trên một khung màn hình, gọi là form Nếu bạn
ñã từng sử dụng chương trình vẽ chẳng hạn như Paint, bạn ñã có sẵn các kĩ năng cần thiết ñể tạo một GUI cho Visual Basic
Phần "Basic" ñề cập ñến ngôn ngữ BASIC (Beginners All-Purpose
Symbolic Instruction Code), một ngôn ngữ lập trình ñơn giản, dễ học, ñược chế ra cho các khoa học gia (những người không có thì giờ ñể học lập trình ñiện toán) dùng
Người mang lại phần "Visual" cho VB là ông Alan Cooper Ông ñã gói môi trường hoạt ñộng của Basic trong một phạm vi dễ hiểu, dễ dùng, không cần phải chú ý ñến sự tinh xảo của Windows, nhưng vẫn dùng các chức năng của Windows một cách hiệu quả Do ñó, nhiều người xem ông Alan Cooper
là cha già của Visual Basic
Khi viết một chương trình trong Visual Basic, ta phải qua hai bước: thiết
kế giao diện và viết lệnh Khi thiết kế giao diện, ta sử dụng các công cụ do Visual Basic cung cấp sẵn Các công cụ này cho phép thiết kế giao diện bằng chuột lẫn bàn phím
Visual Basic ñã ñược Microsoft phát triển qua nhiều phiên bản và ngày càng cung cấp cho người dùng nhiều tính năng mới hữu ích, giúp người lập trình nhanh chóng viết các chương trình một cách dễ dàng và chuyên nghiệp ðến nay, Visual Basic ñã phát triển ñến phiên bản 2005 (nằm trong bộ Microsoft Visual Studio 2005) với nhiều tính năng mới rất hấp dẫn Visual Basic 2005 ñã
hoàn toàn là hướng ñối tượng, tức là nó cho dùng lại các lớp (class), form theo
cách kế thừa thật thoải mái Tuy nhiên, do Microsoft vẫn giữ nguyên tắc dấu và làm sẵn (của VB6) những gì rắc rối phía sau sân khấu ñể ta có thể tập trung vào việc tìm kiếm một giải pháp, thay vì quá bận tâm vào cách thức làm một việc gì Chính nguyên tắc ấy ñã giúp Microsoft chiêu mộ ñược trên 3 triệu VB programmers trên khắp thế giới Visual Basic 2005 cống hiến cho VB
programmers một công cụ rất hữu hiệu ñể dùng cho mọi hoàn cảnh, từ database,
, distributed, internet cho ñến real-time hay mobile (pocket PC)
Trang 21
Những ưu ñiểm của Visual Basic 2005 ñến từ chức năng của NET Framework 2.0, nó mang ñến phương tiện lập trình như XML, Remoting,
Streaming, Serialisation, Threading… Common Language Runtime (CLR) là
trung tâm ñiểm của NET Famework, nó là hầm máy ñể chạy các năng tính
của NET Trong NET, mọi ngôn ngữ lập trình ñều ñược dịch ra Microsoft
Intermediate Language (IL) giống như byte code của Java Nhờ bắt buộc mọi ngôn ngữ ñều phải dùng cùng các kiểu dữ liệu (gọi là Common Type System) nên Common Language Runtime có thể kiểm soát mọi giao diện, gọi giữa các
thành phần và cho phép các ngôn ngữ có thể hợp tác nhau một cách thông suốt Tức là trong NET, chương trình VB.NET có thể thừa kế từ chương trình C# và ngược lại một cách hoàn toàn tự nhiên
Visual Basic 2005 khắc phục những giới hạn về ñối tượng (Object
Oriented) của VB6 và mang ñến cho ta một ngôn ngữ lập trình hoàn toàn hướng ñối tượng Gần như mọi thứ trong Visual Basic 2005 ñều có liên hệ với Object Một ưu ñiểm nữa, Visual Basic 2005 hỗ trợ rất tốt tiếng Việt
Unicode, tất cả các thành phần của ứng dụng như form, button, label,
messagebox, … ñều ñược hỗ trợ tối ña Người lập trình sẽ không còn phải vất
vả khi muốn hiển thị chính xác tiếng Việt cũng như các ngôn ngữ khác trong giao diện chương trình
Việc sử dụng Visual Basic 2005 sẽ giúp người lập trình có ñược những chương trình có giao diện ñẹp, ñáp ứng tốt những nhu cầu của người sử dụng
mà không mất quá nhiều thời gian và công sức
Trang 22
Chương 2 CÁC KHÁI NIỆM CƠ BẢN
Trong các hệ thống truyền tin rời rạc, khi truyền các tín hiệu liên tục, tin tức thường phải thông qua một số phép biến ñổi: ñổi thành số (thường là số nhị phân) rồi mã hoá; ở ñầu thu tín hiệu thông qua những phép biến ñổi ngược với các phép biến ñổi trên: giải mã, liên tục hoá… ñể thu hồi tin tức
Việc mã hoá tin tức nhằm mục ñích tăng hiệu quả và ñộ tin cậy của hệ thống truyền tin, nghĩa là tăng tốc ñộ truyền tin và khả năng chống nhiễu Thông thường tốc ñộ lập tin thường còn rất xa mới ñạt ñược thông lượng của kênh ðể tăng tốc ñộ lập tin, dùng phép mã hoá ñể thay ñổi tính chất thống kê của nguồn, nhờ ñó có thể tiếp cận với thông lượng của kênh Trường hợp kênh có nhiễu, vấn ñề cần phải quan tâm là làm thế nào ñể tăng ñộ chính xác của việc truyền tin, nghĩa là sai nhầm xảy ra là tối thiểu Vấn ñề này cũng có thể ñược cải tiến bằng cách mã hoá
Tóm lại, hai nhiệm vụ lớn mà việc mã hoá cần phải ñạt ñược là: tăng hiệu suất truyền tin và tăng ñộ tin cậy Từ ñây dẫn ñến hai hướng lớn cần
nghiên cứu của việc mã hoá là: mã hoá nén dữ liệu và mã hoá có khả năng
phát hi ện sai và sửa sai
Chương này giới thiệu một số khái niệm cơ bản về mã hoá, các phương pháp biểu diễn mã, các khái niệm về nén dữ liệu và mã hoá có khả năng phát hiện sai và sửa sai
2.1 ðịnh nghĩa và các khái niệm về mã hoá
Trang 23
Trong ñó k là cơ số của bộ mã Ví dụ: k = 2 là mã nhị phân, k = 10
là mã thập phân, k = 16 là mã thập lục phân
Nếu tin xi ñược mã hoá thành: xi ↔ mr1mr2…mrl
Ở ñây l là số ký hiệu của bộ mã dùng ñể biểu diễn xi ñồng thời l
Quãng cách mã là số ký hiệu khác nhau tính theo vị trí tương ứng của 2
từ mã có chiều dài bằng nhau
Gọi W1,W2 là 2 từ mã có chiều dài bằng nhau
Quãng cách mã d(W1,W2)=w(W1 ⊕W2) với ⊕ là phép toán cộng modul
2
Ví dụ: W1 = 0011001, W2 = 1011101 thì d(W1,W2) = w(W1 ⊕W2)=2 Quãng cách của một bộ mã ñược ñịnh nghĩa là quãng cách mã tối thiểu của hai từ mã bất kỳ của bộ mã [12]
Trang 24
2.1.3 Các phương pháp biểu diễn mã
2.2.2.1 Phương pháp liệt kê
ðây là cách biểu diễn ñơn giản nhất: liệt kê trong một bảng những tin của nguồn và chỉ rõ các từ mã tương ứng
B ảng 2.1 Bảng mã các tin trong nguồn tin A
Cách biểu diễn này tuy rõ ràng nhưng không thích hợp cho trường hợp
bộ mã lớn và cồng kềnh
2.2.2.2 Phương pháp mặt phẳng toạ ñộ của mã
Phương pháp này chỉ thích hợp cho các loại mã có trọng số Dựa vào hai thông số là ñộ dài n và trọng số b của từ mã ñể lập nên một mặt phẳng toạ ñộ Mỗi từ mã ñược biểu diễn bằng một ñiểm trên mặt phẳng toạ ñộ (n, b) Nếu từ
mã v = (v0, v1, …vn) ñược mã hoá bởi bộ mã M có cơ số là m: v1∈M và vi =0, 1,…, m-1 với i = 1, 2,…, n Trong ñó quy ước vị trí ñầu tiên bên trái ứng với
kí hiệu v1 là vị trí có trọng số nhỏ nhất: m0, vị trí thứ i tính từ trái sang phải ứng với kí hiệu vi có trọng số là mi-1, vị trí cuối cùng (thứ n) tương ứng với vn
có trọng số là mn-1 Khi ñó, trọng số b của từ mã là tổng trọng số các kí hiệu trong từ mã ñược tính theo công thức sau:
1 1
Trong ñó:
vi: giá trị của kí hiệu thứ i trong từ mã, vi∈M
i: số thứ tự của kí hiệu trong từ mã, i = 1,…, n
m: cơ số của mã
Trang 25ở nút mức i+1 Nút lá biểu diễn cho một từ mã mà thứ tự các giá trị kí hiệu ñi
từ nút gốc ñến nút lá qua các nút trung gian
Ví d ụ: Cây mã cho bộ mã 00, 01, 100, 1010, 1011 ñược biểu diễn trên hình
2.2 Từ cây mã, có thể nhận biết mã ñã cho là loại mã ñều hay không ñều, loại
Trang 26
mã ñầy hay vơi Mã là ñều khi các nút lá có cùng bậc, còn ngược lại là không ñều; mã là mã ñầy khi tất cả các nút trung gian bậc trước các nút lá ñều có m nhánh
Hình 2.2 Cây nh ị phân cho bộ mã 00, 01, 100, 1010, 1011
2.2.2.4 Phương pháp ñồ hình kết cấu
Gồm những nút và những nhánh có hướng ðây là một cách biểu diễn cây mã rút gọn Mỗi từ mã ñược biểu diễn bằng một vòng tròn khép kín xuất phát từ nút gốc theo các nhánh có hướng (chiều mũi tên) qua các nút trung gian và trở về kết thúc tại nút gốc Thứ tự giá trị các kí hiệu lấy theo thứ tự
giá trị các nhánh trên ñường ñi Ví dụ:
Hình 2.3 ðồ hình kết cấu của bộ mã 00, 01, 100, 1010, 1011
Trị các nhánh ñược ghi ở ñầu xuất phát của nhánh Dấu V biểu diễn toán
tử hoặc (OR), các nút ñược ñánh số theo thứ tự xa dần nút gốc (số ghi trong vòng tròn của nút) ðồ hình kết cấu không những chỉ dùng mô tả mã mà còn ñược dùng ñể xét cách vận hành thiết bị mã hoá và giải mã
(100) (1010) (1011)
Trang 272,2)(
i i i i
n n
n n
2.2.2.7 Phương pháp dùng ña thức sinh
Phương pháp này dùng làm mô hình toán ñể biểu diễn mã ña thức (mã vòng) Nhờ công cụ toán này có thể dễ dàng tạo mã và giải mã ñối với mã vòng
Tóm lại, có nhiều cách ñể biểu diễn mã Mỗi phương pháp có ưu ñiểm và khuyết ñiểm riêng Tuỳ theo từng trường hợp mà sử dụng phương pháp nào cho phù hợp
2.1.4 ðiều kiện ñể mã phân tách ñược và mã có tính Prefix
ðiều kiện quan trọng của việc tạo mã là cho phép khi nhận ñược một chuỗi các kí hiệu, chúng phải tách ra ñược thành các thành phần cơ bản là các
từ mã cách tách này phải là duy nhất và ñúng ðể ñạt ñược ñiều này thì bộ mã phải thoả ñiều kiện cần và ñủ sau: bất kì dãy các từ mã nào của bộ mã cũng không ñược trùng với một dãy từ mã khác của cùng bộ mã
Một thông số ñược ñưa ra ở ñây là ñộ chậm giải mã ðộ chậm giải mã
ñược ñịnh nghĩa là số kí hiệu nhận ñược cần thiết có thể phân tách ñược thành các từ mã ðối với bộ mã phân tách ñược, ñộ chậm giải mã là hữu hạn nhưng
Trang 28Trong các loại mã có tính phân tách ñược, loại mã mang nhiều ñặc ñiểm
có ích cho việc khai thác sử dụng và ñược nghiên cứu nhiều là mã có tính
prefix ðây cũng là một loại mã mà chúng tôi sẽ sử dụng trong luận văn này
Ta có thể hiểu prefix (phần ñầu) của một từ mã là bộ phận của từ mã ñó sau khi bỏ ñi các kí hiệu cuối cùng Ví dụ: từ mã 011001110 có các prefix
Trong thực tế, các loại mã không ñồng ñều mà không có tính prefix
không ñược nghiên cứu vì không có giá trị thực tế, lí do là các thiết bị mã hoá
Trang 29
Nhìn chung không thể có phương pháp nén tổng quát nào cho kết quả tốt ñối với tất cả các loại tập tin vì nếu không ta sẽ áp dụng n lần phương pháp nén này ñể ñạt ñược một tập tin nhỏ tuỳ ý Kĩ thuật nén tập tin thường ñược
áp dụng cho các tập tin văn bản (trong ñó có một số kí tự nào ñó có xác suất xuất hiện nhiều hơn các kí tự khác), các tập tin ảnh bitmap (mà có thể có những mảng lớn ñồng nhất), các tập tin dùng ñể biểu diễn âm thanh dưới dạng
số hoá và các tín hiệu tương tự (analog signal) (các tín hiệu này có thể có các
mẫu ñược lặp lại nhiều lần) ðối với các tập tin nhị phân như tập tin chương trình thì sau khi nén cũng không tiết kiệm ñược nhiều
2.2.2 Tầm quan trọng của việc nén dữ liệu
Ngày nay các phương pháp nén dữ liệu ñã phát triển rất mạnh mẽ, ñược nghiên cứu và ứng dụng nhiều trong thực tế Mục tiêu chính của các phương pháp nén dữ liệu là:
- Tiết kiệm dung dung lượng bộ nhớ lưu trữ Vì file lưu trữ không phải ở
dạng ñã ñược nén thì thực sự thông tin dư thừa rất nhiều Ví dụ trong các văn bản rất nhiều từ và kí tự ñược lặp ñi lặp lại thậm chí cả những cụm từ ñược lặp ñi lặp lại rất nhiều lần Một ví dụ ñiển hình như dấu trắng xuất hiện rất nhiều lần trong các file văn bản Trong các file ảnh tình trạng này càng dư thừa nhiều ñó là rất nhiều các phần hình giống nhau Ngay cả ở trong những file dữ liệu mà thông tin chuyển vào rất ngẫu nhiên như file COM, file EXE thì việc dư thừa rất nhiều thông tin dù rằng ít hơn file văn bản và file ảnh
- Nếu truyền dẫn các file dữ liệu này trên một môi trường truyền thông ví
dụ như mạng diện rộng của cả nước hay trong phạm vi từ tỉnh này sang tỉnh
kia thì do dữ liệu ñược nén lại cho nên làm tăng tốc ñộ truyền dẫn Trong kĩ
thuật truyền tin do các bit ñược truyền bị giới hạn vể dải thông của kênh truyền, giới hạn về các chuẩn ghép nối… nên tốc ñộ tương ñối chậm Nén dữ liệu trước khi truyền ñi là một trong các phương pháp làm tăng tốc ñộ truyền
dữ liệu Trong các modem hiện ñại, việc thực hiện nén dữ liệu trước khi truyền ñi có thể ñược thực hiện ngay trong modem theo các giao thức v42bis, MNP5 Hoặc theo một phương pháp khác là thực hiện nén các tập tin ngay tại
Trang 30
các máy vi tính trước khi truyền ñi, tại các máy nhận, các tập tin lại ñược giải nén ñể phục hồi lại dạng ban ñầu Với phương pháp này, các máy tính phải tốn thêm thời gian nén và giải nén, nhưng do sự phát triển nhanh chóng của các bộ vi xử lí mà thời gian thực hiện nén và giải nén ñược giảm nhỏ hơn rất nhiều thời gian truyền dữ liệu
- Giữ ñược an toàn và bảo mật thông tin
Hiện nay người ta ñã dùng rất nhiều phần mềm nén dữ liệu, trong nhiều trường hợp nó có khả năng nén từ 30-40% thậm chí có nhiều trường hợp ñạt
từ 80-90% hoặc trên 90% tuỳ theo dạng file dữ liệu
2.2.3 Phân loại
Có hai phương pháp nén căn bản: nén có thất thoát, trong ñó một số dữ liệu sẽ bị mất khi các tập tin ñược giải nén; nén bảo toàn, không làm mất dữ liệu khi tập tin ñược phục hồi ñịnh dạng gốc
2.2.3.1 Nén bảo toàn thông tin
Kĩ thuật nén bảo toàn thông tin tức là nén mà không loại bỏ hay làm mất bất kì thông tin nào Khi tài liệu gốc ñược giải nén, nó giữ nguyên thông tin ban ñầu ñến từng bit [9]
Chương trình nén bảo toàn thông tin tìm dữ liệu thừa hoặc lặp lại trong toàn bộ tài liệu và sau ñó mã hoá Ví dụ, một văn bản có chứa 200 khoảng trắng, 100 từ “in” và 50 từ “the defendant said” chương trình tìm những từ, ngữ, khoảng trắng lặp này và thay chúng bằng chuỗi bit hay kí hiệu số cho từng loại rồi lưu trong “từ ñiển” Khi giải nén tập tin, chuỗi bit ñược giải mã
và dữ liệu ñược phục hồi Dữ liệu không bị mất hay thay ñổi Giả sử ta có dữ liệu nguồn là D và dữ liệu nén là D’, sau khi giải nén D’ thì ñược tập D’’ mà tập D’’ hoàn toàn giống với tập D ban ñầu Có rất nhiều chương trình nén dữ liệu như Stufflt (cho Macintosh) của Aladdin Systems, WinZip (cho Windows) của WinZip Computing và PKZip của PKWare PKZip là một trong những chương trình nén phổ biến nhất cho DOS và Windows
Trang 31
Sự phát triển của Internet cũng làm cho việc nén trở nên quan trọng vì dung lượng, băng thông chính là tiền bạc Tài liệu thông thường như bảng tính Microsoft Excel hay Word hoặc PowerPoint có thể thu nhỏ một nửa kích thước ban ñầu, những tài liệu có nhiều con số và sự lặp lại có thể nén xuống còn 20% kích thước ban ñầu
Với nén bảo toàn thông tin, nhiều thuật toán ñã ñược phát triển và có giá trị thực tế cao, có thể kể tên các thuật toán tiêu biểu: Huffman (do David
A Huffman ñưa ra năm 1952), mã Fano-Shanon, LZ77 và LZ78 (do Jacov Ziv và Abraham Lempel giới thiệu năm 1977-1978), LZW (ñược Terry Welch phát triển trên cơ sở thuật toán của Jacov Ziv và Abraham và ñưa ra giới thiệu năm 1984)
2.2.3.2 Nén thất thoát thông tin
Bên cạnh nén bảo toàn thì người ta còn ñưa ra khái niệm nén không bảo toàn Nén không bảo toàn là mô hình nén dữ liệu mà tính bảo toàn dữ liệu không ñược coi trọng, một số dữ liệu sẽ bị mất khi các tập tin ñược giải nén
Có nghĩa là nếu ta có tập dữ liệu D, tập nén D’ thì sau khi giải nén ta thu ñược tập tin D’’ khác tập tin D ban ñầu ðối với tín hiệu âm thanh, hình ảnh, video
có thể nén xuống còn 5% so với kích thước gốc Tai và mắt người khó có thể phát hiện ñược sự thất thoát dữ liệu này Ví dụ hình ảnh bị mất thông tin có thể không sắc nét bằng hình ảnh gốc nên làm cho những lá cỏ dường như bị
mờ ñi
2.2.4 Giới thiệu một số chuẩn nén
Joint Photographic Experts Group (JPEG): Phương pháp nén ảnh tĩnh với
tỉ lệ nén lên ñến 20-1 mà không làm mất thông tin ñánh kể
Lempel-Ziv-Welch: Giải thuật này ñược dùng trong nhiều ñịnh dạng nén,
kể cả ñịnh dạng có thể trao ñổi ñồ hoạ và Tag Image File Format mà ta thường gọi là TIFF
Moving Pictures Experts Group (MPEG): Phương pháp nén thất thoát thông tin dùng cho video MPEG-1 dùng cho CD-ROM và Video CD MPEG-2 nén video cho truyền hình thông thường và ñộ nét cao
MPEG Audio Layer 3 (MP3): Công nghệ nén âm thanh sử dụng một phần chuẩn MPEG-1 ñể nén âm thanh chất lượng CD với hệ số 12
Trang 32Wavelet: Dạng nén thất thoát thông tin sử dụng hàm toán học ñể nén hình ảnh với tỷ lệ lớn hơn những phương pháp khác – có thể ñạt ¼ kích thước của cùng bức ảnh nén bằng JPEG
Windows Media Technology: Sản phẩm của Microsoft, cho chất lượng
âm thanh tốt hơn MP3 ñối với tập tin cùng kích thước, cũng như chất lượng video gần bằng DVD
2.3 Mã hoá có khả năng phát hiện sai và sửa sai
2.3.1 Khái niệm
Mã hoá có khả năng phát hiện sai và sửa sai có thể hiểu ñơn giản ñó là phương pháp mã hoá dữ liệu số nhằm tăng ñộ tin cậy khi truyền tin bằng cách thêm vào trong bản tin một số lượng thông tin nhằm mục ñích kiểm soát, phát hiện và sửa các lỗi trong trường hợp kênh truyền có nhiễu và bản tin nhận ñược không chính xác
2.3.2 Tầm quan trọng của việc mã hoá sửa sai
Với phương pháp này, ta có thể phát hiện các lỗi xảy ra khi truyền tin (có thể sai, hỏng một số bit dữ liệu nào ñó), ñồng thời, dựa vào lượng thông tin kiểm soát lỗi trong bản tin, ta có thể khôi phục lại bản tin như ban ñầu Tuy nhiên, không phải trường hợp nào phương pháp này cũng ñem lại kết quả tốt (chẳng hạn: bản tin nhận hỏng quá nhiều hay hỏng xảy ra ñối với chính ñoạn thông tin kiểm soát lỗi…), trong các trường hợp này thì hầu như bản tin không thể khôi phục ñược
Hiện nay, có rất nhiều phương pháp ñược áp dụng hòng kiểm soát lỗi khi truyền tin: phương pháp mã khối tuyến tính, phương pháp Hamming, mã vòng, mã BCH, mã xoắn… Mỗi phương pháp có những ưu ñiểm và nhược ñiểm riêng, nhưng nói chung các phương pháp cũng ñã ñem lại hiệu quả cao trong việc kiểm soát, sửa lỗi khi truyền tin
Trang 33
Chương 3 THUẬT TOÁN NÉN DỮ LIỆU
Chương này trình bày các thuật toán nén dữ liệu không mất mát thông tin
và chi tiết cài ñặt của các thuật toán tiêu biểu ðể mã hoá nén dữ liệu ta phải
sử dụng mô hình dữ liệu vào Nói chung, có hai dạng chính: dạng thống kê (sử dụng bảng tần số xuất hiện) và dạng từ ñiển (dùng phương pháp so sánh các dãy kí tự với nhau)
3.1 Các thuật toán nén dữ liệu theo kiểu thống kê
Thông thường, các tập tin máy tính có rất nhiều thông tin dư thừa Chương trình nén của chúng ta sẽ cố gắng giảm ñến mức thấp nhất lượng thông tin dư ñó Các phương pháp dưới ñây sẽ thực hiện nén tập tin theo cách thống kê các kí tự có trong tập tin, sau ñó dựa vào bảng tần số xuất hiện của các kí tự mà có biện pháp ñể thực hiện giảm kích thước tập tin Nói chung, các phương pháp này ñơn giản, dễ xây dựng, không quá tốn thời gian của CPU, tuy nhiên có thể khả năng nén không ñược cao
3.1.1 Phương pháp mã hoá ñộ dài loạt
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
Trang 34Việ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
Trang 35vắ 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 ựồ 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
Trang 36
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 n i
i n
m n
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
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 n i
i n
m n
Trang 37Hình 3.1 S ơ ñồ giải thuật tạo mã Shanon
Ví dụ: Lập mã Shanon cho tập các kí tự u sau:
m n
True
Trang 38)( 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
B ước 5: Duyệt cây từ gốc ñến lá ta sẽ thu ñược các từ mã của các kí tự
Trang 39
Hình 3.2 S ơ ñồ giải thuật tạo 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 t ập kí tự u = {u 1 , u 2 , …, u 7 }
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
Trang 40- 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
- 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