1

我正在用 C 编写一个自定义压缩算法,它读取 ascii 字符,从每个字符中删除第一个位(因为它始终为 0),然后将其粘贴到一个新文件中。它使输入成为原始大小的 7/8。这是压缩:

#include <stdio.h>

int main()
{
  int i = 1;
  int c;
  unsigned short value = 0;

  while((c = getchar()) != EOF)
  {
    value = (c << i) | value;
    if(i != 1) putchar(value >> 8);
    value = value << 8;
    i++;
    if(i == 9) i = 1;
  }
  if(i != 1) putchar(value >> 8);
}

这是解压:

#include <stdio.h>

int main() {

  int i = 1;
  int c;
  unsigned char value = 0;

  while((c = getchar()) != EOF) {
    value = (c >> i) | value;
    putchar(value);

    value = (c << (8-i)) | 0;
    value = value >> 1;

    if(++i == 8) {
      putchar(value);
      i = 1;
    }
  }
}

如果我压缩“ororororor”(不带引号)之类的内容,然后解压缩,则输出为“orororor.r”,其中“。” 十六进制为 7F。但是,如果我给它“ororororrr”,那么它会输出正确的“ororororrr”。它只会在某些输入时失败,但我找不到当它搞砸时的模式。

抱歉,这不在函数中。我一直在使用它的方式是在 UNIX 中使用以下命令:

echo -n your input here > data
gcc compress.c
./a.out < data > inp
gcc decompress.c
./a.out < inp > out
hexdump -C out
4

2 回答 2

1

您是否考虑了输入甚至不会落在 8 位边界上的情况?有点像base 64编码在做同样的事情时遇到的问题......

于 2012-09-13T21:40:23.687 回答
1

value一个问题肯定是你在解压时没有归零。

在您到达文件末尾之前,这没有效果(多余的位被轮换)。

尝试:

 if(++i == 8) {
     putchar(value);
     i = 1;
     value = 0; // Clean up
 }

测试用例(value如果有命令行参数,则将上述程序修改为零):

  echo "xxxxxxxRxx" | ./comp | ./decomp OK
  xxxxxxxRxx
  echo "xxxxxxxRxx" | ./comp | ./decomp
  xxxxxxxRzx
于 2012-09-13T21:46:00.830 回答