从8位压缩到7位c.



我是新来的,所以我希望这是正确的地方问。我的任务是压缩一个包含8位字符到7位字符的文本文件,以节省空间,并能够将其还原并解码回8。由于最后一位总是0,这是一种无损压缩(假设我们在127之后不使用ASCII字符)我意识到有一个相对类似的帖子(压缩8字符在7字节),但我采取的方法是完全不同的,我想知道为什么它不起作用,以及如何改进这个想法。

我对压缩的想法如下:压缩位[i]应该是i+偏移位右移i+ 1% 8,当偏移量每除以8增加1

,对于解码部分:新位[i]应该等于压缩位[i]右移i次&~ 1

如果可以的话,我会上传我的逻辑草图,但是代码就足够了。

的输出都是我写入和读入f的文件,是在这段代码之前完成的,并且经过了测试

压缩代码:

int offset = 1,size = strlen(f); //f is a char* buffer that I read the whole file to
for(int i = 0; i < size; i++)
{
if(offset%8 == 0)
offset++;
shift_right(f,size,(i+1)%8);
fputc(f[i+offset],output);
}

解码码:

unsigned char temp;
for (int i = 0; i < actualLen; ++i) //actualLen being the length of the uncompressed file in chars(bytes)
{
temp = f[i]&(~1);
fputc(temp,output);
shift_right(f,actualLen,1); //f is a char* buffer that I read the whole file to
}

右移函数:

void shift_right(unsigned char *ar, int size, int shift)
{//credit to another post here for this function :)
int carry = 0;                              // Clear the initial carry bit.
while (shift--) {                           // For each bit to shift ...
for (int i = size - 1; i >= 0; --i) {   // For each element of the array from high to low ...
int next = (ar[i] & 1) ? 0x80 : 0;  // ... if the low bit is set, set the carry bit.
ar[i] = carry | (ar[i] >> 1);       // Shift the element one bit left and addthe old carry.
carry = next;                       // Remember the old carry for next time.
}
}
}

谢谢你的帮助:)

压缩意味着写入的输出字节数少于输入字节数。在最简单的层面上,您的程序无法工作,因为它不适合这样做。循环遍历文件的所有字节:

for(int i = 0; i < size; i++)
{

并且不管你执行的计算,对于输入的每个字节你…

fputc(f[i+offset],output);
}

这可以实现某种密码,但它总是为每一个字节的输入提供一个字节的输出(因此,没有压缩)。

我认为这里有一个基本的概念错误,因为这个想法…

压缩位[i]应该是右移i+1的i+偏移位当I除以8时,每次偏移量增加1

…似乎描述了一个在上操作的算法,整个输入作为一个位数组,但是你已经尝试在每个字节上单独实现它。

还有一个可能的次要错误,因为你谈论右移,但从位数组的角度来看,你似乎实际上想要移位,因为我们通常认为二进制数是从最高有效位到最低有效位,而术语"左移";右移;都是用这种表示来定义的。左移将位移动到更重要的位置(在位数组视图中==指向数组的前面),而右移将它们移动到相反的方向。如果你根本不提到移动,你的描述实际上更符合我认为你的想法:

"压缩位[i]应该是输入位[i+offset],其中offset从1开始,每次8除i&gt时增加1;

0 !">

请注意,除了最后一个输出字节外,每个输出字节都包含两个输入字节的位,每个7个输出字节的块都包含8个输入字节的所有位。这就是我的实现建议的基础:

  • 维护一个8字节的输入缓冲区和一个7字节的输出缓冲区。
  • 每次读取输入8字节,并根据您的方案将它们打包到输出缓冲区的7字节中。
  • 输出每个完整的7字节压缩组作为一个单位
  • 不要忘记对文件的最后一块实现适当的处理,它通常不会包含完整的8字节。

最新更新