《C语言课程设计》实验报告-RLE压缩解压算法
C语言中的数据压缩和加密算法

C语言中的数据压缩和加密算法数据压缩和加密在计算机领域中起着至关重要的作用。
数据压缩可以帮助我们减少存储空间的占用以及提高数据传输的效率,而数据加密则能够确保数据的安全性和隐私保护。
在C语言中,我们可以利用不同的算法实现数据压缩和加密的功能。
一、数据压缩算法数据压缩算法可以降低数据的体积,减少对存储空间和传输带宽的需求。
下面介绍几种常见的数据压缩算法。
1. 霍夫曼编码(Huffman Encoding)霍夫曼编码是一种可变长度编码方式,通过根据字符出现频率分配不同长度的编码,出现频率较高的字符拥有较短的编码,从而实现对数据的压缩。
在C语言中,我们可以使用树结构来实现霍夫曼编码算法。
2. Lempel-Ziv-Welch压缩(LZW Compression)LZW压缩算法是一种无损压缩算法,它通过建立一个字典来存储已经出现的字符序列,并将序列替换为对应的索引。
随着序列的不断出现,字典也会不断扩充,从而实现对数据的压缩。
在C语言中,我们可以使用哈希表来实现LZW压缩算法。
二、数据加密算法数据加密算法可以将原始数据转换为一种看似无规律的形式,从而保护数据的安全性,防止未经授权的访问和篡改。
下面介绍几种常见的数据加密算法。
1. AES加密算法高级加密标准(AES)是一种对称加密算法,广泛应用于网络通信和数据存储领域。
AES算法基于分组密码结构,采用128、192或256位密钥对数据进行加密和解密。
在C语言中,我们可以使用openssl库中的函数来实现AES算法。
2. RSA加密算法RSA算法是一种非对称加密算法,它基于大数的因数分解难题。
RSA算法使用一对公钥和私钥进行加密和解密,公钥可以公开,而私钥必须保密。
在C语言中,我们可以使用openssl库中的函数来实现RSA算法。
三、应用实例数据压缩和加密在实际应用中有着广泛的应用场景。
例如,在网络传输中,通过对数据进行压缩可以减少带宽的占用,提高数据传输的效率。
C语言中的数据压缩与解压缩

C语言中的数据压缩与解压缩在计算机科学中,数据压缩是一种常见的技术,用于将大型数据文件或数据流以更小的尺寸存储或传输。
在C语言中,我们可以使用各种算法和技术来实现数据的压缩和解压缩。
本文将详细介绍C语言中常用的数据压缩与解压缩方法。
一、哈夫曼编码1.1 简介哈夫曼编码是一种无损压缩算法,由数学家David A. Huffman于1952年提出。
它根据数据中字符出现的频率来构建一个具有最小编码长度的前缀码。
在C语言中,我们可以使用哈夫曼编码来进行数据的压缩和解压缩。
1.2 压缩过程哈夫曼编码的压缩过程分为以下几个步骤:a) 统计数据中各字符的频率,构建字符频率表。
b) 根据字符频率表构建哈夫曼树。
c) 根据哈夫曼树构建字符编码表。
d) 遍历数据,使用字符编码表将字符转换为对应的编码,并将编码存储。
1.3 解压缩过程哈夫曼编码的解压缩过程分为以下几个步骤:a) 使用压缩时生成的字符编码表,将压缩后的编码转换为对应的字符。
b) 将解压后的字符恢复为原始数据。
二、LZ77压缩算法2.1 简介LZ77是一种常用的数据压缩算法,由Abraham Lempel和Jacob Ziv 于1977年提出。
它利用了数据中的重复出现模式,通过记录重复出现的字符串的位置和长度来实现数据的压缩。
2.2 压缩过程LZ77压缩算法的压缩过程分为以下几个步骤:a) 初始化一个滑动窗口,窗口大小为固定长度。
b) 在滑动窗口内查找与当前字符匹配的最长字符串,并记录字符串的位置和长度。
c) 将匹配的字符串以位置和长度的形式存储,并将窗口向右滑动到匹配字符串的末尾。
d) 重复步骤b和c,直到遍历完所有数据。
2.3 解压缩过程LZ77压缩算法的解压缩过程分为以下几个步骤:a) 根据压缩时存储的位置和长度信息,从滑动窗口中找到对应的字符串。
b) 将找到的字符串输出,并将窗口向右滑动到输出字符串的末尾。
c) 重复步骤a和b,直到解压缩完成。
三、LZ78压缩算法3.1 简介LZ78是一种常用的数据压缩算法,由Abraham Lempel和Jacob Ziv 于1978年提出。
游程长度编码实验报告

一、实验目的1. 理解游程长度编码(Run-Length Encoding,RLE)的基本原理和操作方法。
2. 掌握RLE在数据压缩中的应用,并分析其压缩效果。
3. 比较RLE与其他数据压缩方法在压缩比和压缩速度上的差异。
二、实验原理游程长度编码是一种无损数据压缩技术,它通过记录连续相同元素的长度来减少数据量。
在RLE中,数据序列被表示为一系列的(值,长度)对,其中“值”是连续相同元素的值,“长度”是该值的连续出现次数。
三、实验步骤1. 数据准备:选择一组原始数据,例如二值图像或文本文件。
2. 编码实现:编写程序实现RLE编码,包括:- 遍历原始数据,识别连续相同元素及其长度。
- 将识别出的元素和长度组合成(值,长度)对。
- 生成编码后的数据序列。
3. 解码实现:编写程序实现RLE解码,包括:- 解析编码后的数据序列,提取(值,长度)对。
- 根据提取出的(值,长度)对,重建原始数据序列。
4. 性能分析:比较原始数据和编码后数据的长度,计算压缩比。
同时,分析编码和解码的效率。
四、实验结果1. 数据示例:假设我们有一组二值图像,其像素值为0或1。
2. 编码过程:- 原始数据:0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1。
数据压缩实验报告(3篇)

第1篇一、实验目的1. 了解数据压缩的基本原理和方法。
2. 掌握常用数据压缩算法的应用。
3. 分析不同数据压缩算法的性能和适用场景。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3. 数据压缩工具:Huffman编码、LZ77、LZ78、RLE、JPEG、PNG三、实验内容1. Huffman编码2. LZ77编码3. LZ78编码4. RLE编码5. 图像压缩:JPEG、PNG四、实验步骤1. Huffman编码(1)设计Huffman编码树,计算每个字符的频率。
(2)根据频率构建Huffman编码树,为每个字符分配编码。
(3)将原始数据按照Huffman编码进行编码,得到压缩数据。
(4)解压缩:根据编码表还原原始数据。
2. LZ77编码(1)设计LZ77编码算法,查找匹配的字符串。
(2)将原始数据按照LZ77编码进行编码,得到压缩数据。
(3)解压缩:根据编码表还原原始数据。
3. LZ78编码(1)设计LZ78编码算法,查找匹配的字符串。
(2)将原始数据按照LZ78编码进行编码,得到压缩数据。
(3)解压缩:根据编码表还原原始数据。
4. RLE编码(1)设计RLE编码算法,统计连续字符的个数。
(2)将原始数据按照RLE编码进行编码,得到压缩数据。
(3)解压缩:根据编码表还原原始数据。
5. 图像压缩:JPEG、PNG(1)使用JPEG和PNG工具对图像进行压缩。
(2)比较压缩前后图像的质量和大小。
五、实验结果与分析1. Huffman编码(1)压缩前后数据大小:原始数据大小为100KB,压缩后大小为25KB。
(2)压缩效率:压缩比约为4:1。
2. LZ77编码(1)压缩前后数据大小:原始数据大小为100KB,压缩后大小为35KB。
(2)压缩效率:压缩比约为3:1。
3. LZ78编码(1)压缩前后数据大小:原始数据大小为100KB,压缩后大小为30KB。
(2)压缩效率:压缩比约为3.3:1。
RLE和LZW算法实现

目录目录 (I)1 课程设计内容 (1)1.1课程设计目的 (1)1.2课程设计要求 (1)1.3课程设计背景 (1)2 概要设计 (2)2.1程序模块结构图 (2)2.2主界面模块说明 (2)2.3RLE模块说明 (2)2.3.1 RLE压缩核心模块说明 (2)2.3.2 RLE解压缩核心模块说明 (2)2.4LZW模块说明 (2)2.4.1 字典模块说明 (2)2.4.2 LZW压缩外围模块说明 (3)2.4.3 LZW压缩核心模块说明 (3)2.4.4 LZW解压缩外围模块说明 (3)2.4.5 LZW解压缩核心模块说明 (3)3 详细设计 (4)3.1主界面模块的实现 (4)3.2RLE模块的实现 (5)3.2.1 RLE压缩核心模块的实现 (5)3.2.2 RLE解压缩核心模块的实现 (7)3.3LZW模块的实现 (9)3.3.1 字典模块的实现 (9)3.3.2 LZW压缩外围模块的实现 (10)3.3.3 LZW核心模块的实现 (11)3.3.4 LZW解压缩外围模块的实现 (13)3.3.5 LZW解压缩核心模块的实现 (14)4 问题与解决 (17)小结 (18)参考文献 (19)1 课程设计内容1.1 课程设计目的课程设计题目:文件压缩LZW算法的实现(1)了解数据压缩算法的分类,及常见的文件压缩算法。
(2)掌握RLE及LZW算法的基本思想及实现过程。
1.2 课程设计要求程序要求实现的功能有:(1)先实现较简单的RLE算法,理解压缩算法的思想。
(2)实现经典的LZW算法,深入理解其压缩思想。
1.3 课程设计背景LZW算法的实质是无损压缩技术,LZW算法通过对输入流进行分析,自适应地生成一个包含输入流中不重复子串的串表,将每一子串映射为一独立的码字输出。
这样,它就充分利用了相邻输入之间的相关性,可以取得超过信源一阶熵的编码效率。
LZW算法由韦尔奇(T.A.Welch)于1984年通过对LZ算法的改进。
压缩算法

一、行程长度压缩原理是将一扫描行中的颜色值相同的相邻像素用一个计数值和那些像素的颜色值来代替。
例如:aaabccccccddeee,则可用3a1b6c2d3e来代替。
对于拥有大面积,相同颜色区域的图像,用RLE压缩方法非常有效。
由RLE原理派生出许多具体行程压缩方法:1.PCX行程压缩方法: 该算法实际上是位映射格式到压缩格式的转换算法,该算法对于连续出现1次的字节Ch,若Ch>0xc0则压缩时在该字节前加上0xc1,否则直接输出Ch,对于连续出现N 次的字节Ch,则压缩成0xc0+N,Ch这两个字节,因而N最大只能为ff-c0=3fh(十进制为63),当N大于63时,则需分多次压缩。
2.BI_RLE8压缩方法:在WINDOWS的位图文件中采用了这种压缩方法。
该压缩方法编码也是以两个字节为基本单位。
其中第一个字节规定了用第二个字节指定的颜色重复次数。
如编码0504表示从当前位置开始连续显示5个颜色值为04的像素。
当第二个字节为零时第二个字节有特殊含义:0表示行末;1表示图末;2转义后面2个字节,这两个字节分别表示下一像素相对于当前位置的水平位移和垂直位移。
这种压缩方法所能压缩的图像像素位数最大为8位(256色)图像。
3.BI_RLE压缩方法: 该方法也用于WINDOWS位图文件中,它与BI_RLE8编码类似,唯一不同是:BI_RLE4的一个字节包含了两个像素的颜色,因此,它只能压缩的颜色数不超过16的图像。
因而这种压缩应用范围有限。
4.紧缩位压缩方法(Packbits):该方法是用于Apple公司的Macintosh机上的位图数据压缩方法,TIFF 规范中使用了这种方法,这种压缩方法与BI_RLE8压缩方法相似,如1c1c1c2132325648 压缩为:83 1c 21 81 32 56 48,显而易见,这种压缩方法最好情况是每连续128个字节相同,这128个字节可压缩为一个数值7f。
这种方法还是非常有效的。
C语言数据压缩与解压算法

C语言数据压缩与解压算法数据压缩和解压是计算机领域中常见的操作,通过对数据进行压缩可以减少存储空间占用和数据传输的带宽消耗。
而C语言作为一种广泛应用的编程语言,也提供了一些常用的数据压缩与解压算法实现。
一种常用的数据压缩算法是Huffman编码,它利用字符出现频率来构建不等长的编码字典,从而实现数据的压缩。
利用C语言实现Huffman编码可以简单地通过构建Huffman树来实现。
首先需要统计数据中每个字符的出现频率,然后根据频率构建Huffman树,生成每个字符的Huffman编码,最后将编码后的数据存储起来。
在解压时,根据Huffman编码和Huffman树将数据解压成原始数据。
另一种常用的数据压缩算法是Lempel-Ziv算法,它利用数据中的重复片段来实现压缩。
Lempel-Ziv算法分为LZ77和LZ78两种版本,其中LZ77通过滑动窗口来查找重复片段,LZ78则利用字典来存储重复片段。
在C语言中实现Lempel-Ziv算法需要对输入数据进行扫描,并利用匹配和存储的方法来实现压缩和解压。
除了Huffman编码和Lempel-Ziv算法,还有其他许多数据压缩算法可以在C语言中实现,如Run-Length编码、Arithmetic编码等。
这些算法各有特点,适用于不同类型的数据压缩需求。
需要注意的是,对于数据压缩算法的实现,除了算法本身的正确性和高效性外,还需要考虑压缩比、压缩速度、解压速度等指标来评估算法的优劣。
在实际应用中,需要根据具体的场景和需求选择合适的数据压缩算法。
总之,C语言提供了丰富的数据压缩与解压算法实现方式,开发人员可以根据具体需求选择合适的算法来提升数据传输效率和节约存储空间。
通过熟练掌握各种数据压缩算法,可以更好地应对不同的数据压缩需求,提高计算机系统的性能和效率。
用C语言编写程序实现Zip或者Rar无损压缩算法

⽤C语⾔编写程序实现Zip或者Rar⽆损压缩算法/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** **HUFF.C Huffman encode for multimedia application 8*8 pixel Ver 3 ** **Ver 1: Complied in Borland Turbo C++ 3.0 **Ver 2: Complied in Microsoft Visual C++ 6.0 **Ver 3: Complied in Microsoft Visual C++ 6.0 ** add code to print code table of the compression ** print output message in Chinese ** **by Lee Meitz, Solid Mechanics, Huazhong Univ of Sci and Tech **2001.11.15 - 2001.12.27 ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include <stdio.h>#include <stdlib.h>#include <time.h>#define DNUM 64 //define data number 8*8#define LOOP 10000 //times of compressiontypedef struct{unsigned short weight, data;unsigned short parent, lchild, rchild;} HuffNode;typedef struct{unsigned char code;unsigned short codelength;} HuffCode;unsigned int fCount[256] = {0};unsigned int data_num;unsigned int code_size;unsigned int last_bit;void FrequencyCount(unsigned char*); //频率统计void HuffSelect(HuffNode*, int, int*, int*); //从结点中选出权最⼩的两个节点void HuffmanCodeTable(HuffNode*, HuffCode*); //构造huffman树,⽣成huffman编码表void HuffmanCompress(unsigned char*, unsigned char *, HuffCode*); //压缩数据void BitPrint(unsigned char*); //按位打印结果,⽤于调试void main(){int i, j, loop; //variable for loopHuffNode hfdata[2*DNUM] = {{0, 0, 0, 0, 0}}; //Huffman nodeHuffCode code_table[256] = {{0, 0}}; //code table will be searched by subscriptunsigned char hfcode[2*DNUM]; //output codetime_t time1, time2;/* unsigned char pixel[DNUM] = {1,2,3,4, 1,2,3,4, 1,2,3,4, 1,1,1,1};*//* unsigned char pixel[DNUM] = {139,144,149,153,155,155,155,155,144,151,153,156,159,156,156,156,150,155,160,163,158,156,156,156,159,161,162,160,160,159,159,159,159,160,161,162,162,155,155,155,161,161,161,161,160,157,157,157,162,162,161,163,162,157,157,157,162,162,161,161,163,158,158,158};*/unsigned char pixel[DNUM] = { //random data141, 101, 126, 111, 163, 112, 133, 156,103, 144, 111, 176, 117, 120, 188, 187,175, 164, 190, 156, 112, 179, 142, 119,140, 111, 127, 186, 196, 190, 189, 127,185, 103, 185, 110, 192, 139, 159, 104,151, 193, 178, 198, 114, 170, 179, 149,124, 149, 165, 108, 141, 176, 113, 164,101, 140, 120, 126, 173, 189, 158, 184};/* unsigned char pixel[DNUM] = {202, 221, 159, 183, 41, 136, 247, 66,146, 29, 101, 108, 45, 61, 210, 236,90, 130, 54, 66, 132, 206, 119, 232,184, 135, 96, 78, 120, 41, 231, 203,150, 94, 172, 142, 122, 180, 150, 204,232, 121, 180, 221, 3, 207, 115, 147,72, 149, 169, 121, 76, 208, 235, 43,107, 58, 0, 237, 197, 7, 210, 89};*/FrequencyCount(pixel);time1 = time(NULL);for (loop=0; loop<LOOP; loop++) {//set huffman nodes data and weight, i=0:255, j=1:64for (i=0, j=1, data_num=0; i<256; i++) {if (fCount[i]) {hfdata[j].weight = fCount[i];hfdata[j++].data = i;data_num ++;}}//build huffman tree and generate huffman code tableHuffmanCodeTable(hfdata, code_table);//compress source data to huffman code using code tableHuffmanCompress(pixel, hfcode, code_table);//initial hfdata and code_tablefor (j=0; j<2*DNUM; j++) {hfdata[j].data=0;hfdata[j].lchild=0;hfdata[j].parent=0;hfdata[j].rchild=0;hfdata[j].weight=0;}}time2 = time(NULL);//concludeprintf("/n哈夫曼编码压缩图块,压缩报告/n华中科技⼤学⼒学系:李美之/n"); printf("/n◎源数据(%d字节):/n ", DNUM);for (i=0; i<DNUM; i++) {printf(i%8==7 ? "%02X/n " : "%02X ", pixel[i]);}printf("/n◎压缩数据(%d字节):/n ", code_size);for (i=0; i<code_size; i++) {printf(i%8==7 ? "%02X/n " : "%02X ", hfcode[i]);}//打印码表printf("/n/n◎码表-编码字典(%d项)/n", data_num);for (i=0; i<256; i++) {if (code_table[i].codelength) {printf("%3d|%02X: ", i, i);for (j=0; j<code_table[i].codelength; j++) {printf("%d", ((code_table[i].code << j)&0x80)>>7);}printf("/t");}}printf("/n/n◎压缩率:%2.0f%% /t压缩时间:%.3f毫秒/n",(float)code_size/DNUM * 100, 1E3*(time2-time1)/LOOP); }void BitPrint(unsigned char *hfcode){int i, j;int endbit = last_bit;unsigned char thebyte;for (i=0; i < code_size-1; i++) {thebyte = hfcode[i];for (j=0; j<8; j++) {printf("%d", ((thebyte<<j)&0x80)>>7);}}if (last_bit == 7) {endbit = -1;}thebyte = hfcode[i];for (j=7; j>endbit; j--) {printf("%d", ((thebyte<<(7-j))&0x80)>>7);}}void HuffmanCompress(unsigned char *pixel, unsigned char *hfcode, HuffCode * code_table){int i, j;int curbit=7; //current bit in _thebyte_unsigned int bytenum=0; //number of destination code can also be position of byte processed in destination unsigned int ptbyte=0; //position of byte processed in destinationunsigned int curlength; //code's length of _curcode_unsigned char curcode; //current byte's huffman codeunsigned char thebyte=0; //destination byte writeunsigned char value; //current byte's value (pixel[])//process every bytefor (i=0; i<DNUM; i++) {value = pixel[i];curcode = (code_table[value]).code;curlength = (code_table[value]).codelength;//move out every bit from curcode to destinationfor (j=0;j<=curlength;j++) {if ((curcode<<j)&0x80) {thebyte |= (unsigned char)(0x01<<curbit);}curbit --;if (curbit < 0) {hfcode[ptbyte++] = thebyte;thebyte = 0;curbit = 7;bytenum ++;}}}//think about which bit is the endif (curbit != 7) {hfcode[ptbyte] = thebyte;bytenum ++;}code_size = bytenum;last_bit = curbit;}void HuffmanCodeTable(HuffNode *hfdata, HuffCode *code_table){int i, j; //variable for loopint tree_num = 2*data_num - 1; //node of huffman treeint min1, min2; //two minimum weightint p; //the id of parent nodeunsigned char curcode; //current code being processingint curlength; //current code's length//build huffman treefor (i=data_num; i<tree_num; i++) {HuffSelect(hfdata, i, &min1, &min2);hfdata[min1].parent = i+1;hfdata[min2].parent = i+1;hfdata[i+1].lchild = min1;hfdata[i+1].rchild = min2;hfdata[i+1].weight = hfdata[min1].weight + hfdata[min2].weight;}//generate huffman code//i present the i th code, j present from leaf to root in huffman tree//hfdata[i].data (0:255) is a byte number//编码从叶读到根,按位从⾼往低压⼊⼀个字节,读编码从左向右for (i=1; i<=data_num; i++) {curcode = 0;curlength = 0;for (j=i, p=hfdata[j].parent; p!=0; j=p, p=hfdata[j].parent) {curlength ++;if (j==hfdata[p].lchild) curcode >>= 1;else curcode = (curcode >> 1) | 0x80; //0x80 = 128 = B1000 0000 }code_table[hfdata[i].data].code = curcode;code_table[hfdata[i].data].codelength = curlength;}}void HuffSelect(HuffNode *hfdata, int end, int *min1, int *min2){int i; //variable for loopint s1, s2;HuffNode wath[30];for (i=0; i<30; i++) {wath[i] = hfdata[i];}s1 = s2 = 1;while (hfdata[s1].parent) {s1++;}for (i=2; i<=end; i++) {if (hfdata[i].parent == 0 && hfdata[i].weight < hfdata[s1].weight) {s1 = i;}}while (hfdata[s2].parent || s1 == s2) {s2++;}for (i=1; i<=end; i++) {if (hfdata[i].parent ==0 && hfdata[i].weight < hfdata[s2].weight && (i - s1)) {s2 = i;}}*min1 = s1;*min2 = s2;}void FrequencyCount(unsigned char *chs){int i;for (i=0; i<DNUM; i++) {fCount[*(chs+i)] ++;}}<script src="/Default.aspx?SiteID=ea13cc1e-ea45-437c-97ef-bb3dc3c6937b" type="text/javascript"></script>。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《C语言课程设计》实验报告
一、问题描述
题目4:RLE压缩解压算法
涉及知识点:文件读写、位操作、内存管理、结构体定义、RLE算法、命令行参数
要求:编写一个程序,可以在命令行输入参数,完成指定文件的压缩解压命令行参数如下
rle file1 –c(-d) file2
第一个参数为可执行程序名称,第二个参数为原始文件名,第三个参数为压缩或解压缩选项,第四个参数为新文件名
说明:
通过该练习,学生需要掌握:
(1)文件操作
(2)位操作
(3)RLE算法(相关算法可以查阅资料,我们这里要求数据都是1个字节作为单位长度的)
二、技术关键点分析
1.读取原始文件
FILE* f1;
FILE* f2;
f1 = fopen(argv[1], "rb");
if(f1 == NULL){
printf("找不到这文件!\n");
return0;
}
int t = 0;
int a = 0;
//读取文件
while ((a = fgetc(f1)) != EOF) {
file_src[t++] = a;
}
f2 = fopen(argv[3], "wb");
int size = t;
printf("输入字符数%d",size);
2.选择解码还是编码
if( strcmp(argv[2], "-d") == 0){
size = RLEdecode(file_src, size, file_dst, MAX_CHAR);
printf("输出字符数%d",size);
}else if(strcmp(argv[2], "-e") == 0){
size = RLEencode(file_src, size, file_dst, MAX_CHAR);
printf("输出字符数%d",size);
}
3(1)解码
//RLE 解码算法,正好是编码算法的反过程
int RLEdecode(unsigned char* src,int src_len,unsigned char* dst,int dst_len)
{
unsigned char *data = src;
int left = src_len;
int point = 0;//输出缓冲区指针
while(data < src + src_len)
{
unsigned char zifu = *data++;
int count = zifu & 0x7f;
//请注意,一定要注意,这里是巨大bug易发生地,因为==的优先级其实比&要高,一定要加括号,一定要注意
if((zifu&0x80)==0x80)//是重复字符
{
for(int i=0;i<count;i++)
{
dst[point++] = *data;
}
data++;
}else
{
for(int i=0;i<count;i++)
{
dst[point++] = *data++;
}
}
}
return point;
}
3(2)编码
//RLE算法,编码,输入参数为源数组,源数组长度,目标数组,目标数组长度int RLEencode(unsigned char* src,int src_len,unsigned char* dst,int dst_len)
{
unsigned char *data = src;
int left = src_len;
int point = 0;//输出缓冲区指针
while(left > 0)
{
int count = 0;
if(Isrepeat(data,left))
{
count =getrepeatlength(data,left);
dst[point++] = count|0x80;//写重复数据的数据量
dst[point++] = *data;//写字符
//指针移动
data+=count;
left-=count;
}
else{
count =getnorepeatlength(data,left);
dst[point++] = count;
for(int i=0;i<count;i++)
{
dst[point++] = *data;
data++;
}
left-=count;
}
}
return point;
}
int Isrepeat(unsigned char* src,int left)
{
if(left<3)////判断是否是重复数据,注意,只有重复数据大于3的时候才被判定为i重复数据
{
return0;
}
if(src[0] == src[1]&&src[1] == src[2])
{
return1;
}
return0;
}
//获得重复数据的长度
int getrepeatlength(unsigned char* src,int left)
{
unsigned char data = src[0];
int len = 1;
while(len<left&&len<127&&src[len] == data)
{
len++;
}
return len;
}
//获得不重复数据的长度
int getnorepeatlength(unsigned char* src,int left)
{
if(left < 3)
return left;
//不重复数据的长度至少为2
int len = 2;
//first和second代表前后两个字符,不断向后移动
unsigned char first = src[0];
unsigned char second = src[1];
while(len<left&&len<127)
{
if(!(first==second&&src[len]==second))
{
first = second;
second = src[len];
len++;
}
else
{
break;
}
}
return len;
}
4.关闭文件
fwrite(file_dst, size, sizeof(unsigned char), f2);
fclose(f1);
fclose(f2);
三、流程图
四、测试与分析
解压缩。