提问人:Virgil G. 提问时间:2/12/2023 最后编辑:Virgil G. 更新时间:2/12/2023 访问量:82
如何在 C 中从霍夫曼压缩中解压缩
How to decompress from Huffman's compression in C
问:
我正在开发一个程序来解压缩作为参数传递的文件,并且之前通过霍夫曼算法进行压缩,但我的解压缩功能不起作用,你能帮我吗?
以下是加密格式:
110;;1100;o1101000; 1101001;f1101010;r1101011;
1101100;�1101101;�1101110;{1101111;�1110000;�1110001;�1110010;�1110011;@1110100;61110101;m11101100;h11101101;l11101110;e11101111;01111;
���;o�;�����E}�j�U����͛wo�Ǘ>�@6
我有一个函数来读取文件,另一个函数用于解析霍夫曼代码(在文件顶部)
我的减压功能:
unsigned char *read_bits_from_compressed(unsigned char *str, list_t *code) {
int str_len = strlen(str);
unsigned char padding = str[str_len - 1];
int padding_bits = padding >> 4;
int bits_read = 0;
int curr_byte = 0;
int curr_bit = 7;
int bit = 0;
int i = 0;
int j = 0;
node_t *node = code->head;
cipher_t *cipher = NULL;
unsigned char *result = malloc(str_len);
memset(result, 0, str_len);
for (i = str_len - 2; i >= 0; i--) {
curr_byte = str[i];
for (j = 7; j >= 0; j--) {
bit = (curr_byte >> j) & 1;
while (node != NULL && bits_read < padding_bits) {
node = node->next;
bits_read++;
}
while (node != NULL) {
cipher = (cipher_t *) node->data;
if (cipher->code[curr_bit] == bit) {
curr_bit--;
if (cipher->code[curr_bit + 1] == -1) {
result[str_len - padding - 1 - i] = cipher->c;
node = code->head;
curr_bit = 7;
break;
}
} else {
node = node->next;
curr_bit = 7;
}
}
}
}
return result;
}
该函数必须执行以下操作:
- 反转并从末尾读取字符串。
- 字符串的第一个字符是我们取回的填充
- 一点一点地开始阅读,忽略填充。
- 将整个位表示形式插入到数组中
- 读取数组并检索相应的字符
- 将相应的字符写入输出文件
- 重复直到压缩字符结束(检测并跳过霍夫曼的代码)
以下是链式列表的结构:
列表:
typedef struct list {
node_t *head;
node_t *tail;
size_t size;
} list_t;
节点:
typedef struct node {
struct node *prev;
struct node *next;
void *data;
} node_t;
节点中包含的数据:
typedef struct cipher {
unsigned char c;
int *code;
} cipher_t;
c
对应于 char 和 Huffman 码(由 1 和 0 组成,以 -1 结尾)。code
我的函数当前返回一个空字符串。
答:
0赞
chqrlie
2/12/2023
#1
不能使用 计算压缩数组的长度。 指向可能包含有意义的嵌入 null 字节的二进制数据。您应该将长度作为额外参数传递给 。int str_len = strlen(str);
str
read_bits_from_compressed
事实上,编译器应该抱怨你传递给 which 需要 a (或 .不要忽略编译器警告。unsigned char *
strlen()
char *
const char *
此外,还可以使用 .不能保证解压缩字符串的长度与压缩缓冲区的长度相同。它可能或多或少,具体取决于霍夫曼树和未压缩的值。另请注意,如果您打算生成 C 字符串,则必须为 null 终止符分配 ne 个额外的字节。unsigned char *result = malloc(str_len);
评论
0赞
فِرجِيل
2/12/2023
我忘了提到,在我的压缩算法实现中,没有代码可以值“0”。
2赞
chqrlie
2/12/2023
@VirgilG。即使没有代码可以具有所有位为零,位流中也可能存在与字节边界重合的八个连续零的序列。传递压缩缓冲区长度是必要的。此外,解压缩字符串的长度可能与压缩流的长度(以字节为单位)不同。
评论