jmpjmpje 2023-09-24 15:29 采纳率: 25%
浏览 29
已结题

这是什么压缩算法?如何解压?

《这是什么压缩算法?如何解压?》

鉴于一些原因,这里无法直接贴出原代码。

//--------------------//

首先,产生一个表,初始大小是 256 + 2 头尾2字节为空格,中间的 256字节 对应数据 0 - 255

即,这个表初始是这样的: 空格(20h), 0, 1, 2, 3 .... 254, 255, 空格(20h),所以它的初始大小是 258字节

初始化 2个 重要的 double值, A = 1, B = 0

//--------------------//

循环开始(压缩开始), 对 [原数据 - SrcData] 进行 "逐字节" 地处理。

假设, SrcData[0] 是 74h, 那么:

X = 74h 在[表]中的偏移值。(如, 由于是第0字节, [表]还是初始状态, 所以 X = 75h, 注意 [表] 在后面还会变动! 下面会描述)

Y = (74h + 1) 在[表]中的偏移值。(接上例, Y = 76h)

//--------------------//

计算那2个 double值:

double dbVal = (A - B) / 表的当前长度; (注意表是变动的, 长度也会变动, 下面会描述)
A = B + (dbVal * Y); //接上例, A = 0.45736434108527130
B = B + (dbVal * X); //接上例, B = 0.45348837209302323

将这2个double值转换到 '二进制' 的表示形式,则:

A = 0.011101010001010111010100010101110101000101011101010001

B = 0.011101000001011111010000010111110100000101111101000001

截取出 A B 的 [小数部分] 的 "头部相同部分"

A = 0.011101010 ...
B = 0.011101000 ...

这里可以看到, 相同部分的长度(设为 Z ) = 7, 即为:0111010

那么,这个 0111010 就是最终结果! 即 74h 最终变成了 0111010

注:这里有个需要特别注意的情况, 就是 '相同部分' 的长度为 0, 此时, 直接就是没有结果, 不记录!

例如(只是假设), 原数据: 58 69 05, 58 = 000 69 = 没有结果 05 = 110, 那么这3字节的压缩后会是 000110

//--------------------//

A B 值 步进:

A = A * (1 << Z); //如 A = 0.45736434108527130, Z = 7, 则此处结果为 58.54263565891472609
A = A - 整数部分; //也就是说, 只取 [小数部分], 那么 A 最终结果是 0.54263565891472609

而 B 值也是同样的计算:

B = B * (1 << Z);
B = B - 整数部分; //接上例, 此时 B 值为 0.046511627906973274

//--------------------//

在最后, 对 [表] 进行变动!

取 Y 值; (注: Y = (原数据 + 1) 在[表]中的偏移值)

在 "表[Y]" 处, 插入(增加) 14个 0, 注意表的长度也增加 14 //注, 14 这个值是可以通过输入参数来配置的, 比如, 可以设为 27, 那么压缩结果会不同(这个有点像压缩级别?)

//--------------------//

至此, 当前1个字节处理完毕; 将继续处理下一个字节: 即 SrcData[1], SrcData[2], ... 直至处理完;

在处理完之后, 记录 B 的 "最后值":

假设 SrcData 只有 1个字节, 即, 74h, 处理后为 0111010

处理完后 B 值为: 0.046511627906973274, 其二进值为: 0.00001011111010000010111110100000101111101000001 (只取 [小数部分])

特别注意! 此时 B值 的二进制,如果后面有 0 存在,是要删除掉的! 长度是不固定的!至少看起来没有方法来确定它的长度。

那么最终得到的, 压缩后的数据是: 0111010 + 00001011111010000010111110100000101111101000001, 即: 011101000001011111010000010111110100000101111101000001

然后, 还会将 "原数据的原始长度"(即 解压后长度), 通知给 <解压方>

//--------------------//

经实测, "test12345", 压缩后的最终结果为: 011101000111011101111110111100001101111101110110110001010110111101001101100100001110110101011011101101101111001

然后将二进制转换到十六进制(每次取8bit为1字节): 74 77 7e f0 df 76 c5 6f 4d 90 ed 5b b6 f2 //此转换只是方便存储与转输, 与压缩算法没有实质性的关联

经实测, 一段长度为 256字节的数据, 压缩后可达到 100多字节; 一段 500多的字节的数据, 可以压缩到 400字节左右。

//--------------------//

它的代码并不复杂,我已经用 C语言 自己写了一个函数, 然后对原程序进行多次反复调试, 对不同的数据进行压缩, 然后对比结果, 都是一样的。

现在是不明白它的压缩原理是什么, 或者是叫什么压缩算法, 该如何去解压;

请指教, 谢谢!

  • 写回答

13条回答 默认 最新

  • 2301_76247172 2023-09-24 21:20
    关注

    这是区间编码的另类实现,都由算术编码而来。你先搞清楚 算术编码

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • 前网易架构师-高司机 游戏服务器领域优质创作者 2023-09-25 08:22
    关注

    这个是典型的区间编码算法
    解压和你的编码规则有关

    评论 编辑记录
  • Hi 小朋友 2023-09-24 15:35
    关注

    压缩算法是指数据压缩的算法,在电子与通信领域常被称为信号编码,包括压缩和还原两个步骤。

    例如,在处理多媒体数据时,由于数据量巨大,需要压缩,同时由于存在各种冗余,所以可以压缩。

    评论
  • 专家-赤兔[在线] 2023-09-24 15:36
    关注

    引用 皆我百晓生 小程序回复内容作答:
    根据提供的信息,这个压缩算法是通过将8位数据转换为其二进制表示形式,并根据计算的A和B值对其进行压缩的方法。

    要解压数据,您需要以相同的方式计算A和B的值,并根据这些值将二进制数据逐字节还原为原始数据。

    具体的解压步骤如下:

    1. 从压缩数据中获取A和B的值.
    2. 根据表的大小和A的二进制表示的长度计算出A的小数部分.
    3. 通过计算,得到解压数据的第一个字符.
    4. 更新A和B的值.
    5. 重复以上步骤,直到解压完所有的压缩数据.

    需要注意的是,解压的过程与压缩的过程是相反的,您需要使用压缩数据中的值来计算解压后的数据。

    评论 编辑记录
  • 数据大魔王 2023-09-24 16:39
    关注

    这个压缩算法是一个非常特殊的自定义算法,不太像常见的压缩算法(如gzip、zlib、Lempel-Ziv-Welch等)。它似乎采用了一种基于表的方法,通过记录和重建一系列数据的模式来进行数据压缩。
    解压这种自定义的压缩算法需要知道压缩过程中使用的规则和算法。通常,压缩算法有两个主要部分:压缩和解压。压缩部分将原始数据转换为压缩数据,而解压部分将压缩数据还原为原始数据。
    正确解压数据,需要实现与压缩部分相反的操作。
    以下是一般步骤来解压数据:

    将压缩数据转换为二进制表示。
    从二进制表示中提取出溶解参数(A和B的二进制表示)。
    根据溶解参数,计算出原始的A和B的值。
    从二进制表示中提取出相同部分的长度(Z的二进制表示)。
    根据相同部分的长度,从二进制表示中提取出A和B的小数部分。
    根据A和B的小数部分,计算出原始的A和B的值。
    根据原始的A和B的值,计算出原始的X和Y的值。
    根据X和Y的值,查找表中对应的字符。
    重复上述步骤,直到解压完整个数据流。

    评论
  • CSDN-Ada助手 CSDN-AI 官方账号 2023-09-24 18:43
    关注

    【以下回答由 GPT 生成】

    这段代码使用了基于浮点数算法的压缩算法。下面是解压的具体步骤:

    1. 首先,读入压缩后的数据以及原始数据的长度。
    2. 初始化两个重要的双精度浮点数A = 1,B = 0。
    3. 创建一个表,初始大小为256 + 2字节,头尾2字节为空格,中间的256字节对应数据0 - 255。
    4. 循环开始(解压开始),根据压缩后的数据逐位进行处理。
    5. 使用头部相同部分的长度作为索引,在表中查找对应的X和Y值。
    6. 计算两个双精度浮点数dbVal = (A - B) / 表的当前长度,A = B + (dbVal * Y),B = B + (dbVal * X)。
    7. 将新计算出的浮点数转换为二进制形式,取小数部分作为解压后的结果。
    8. 将解压后的结果写入输出文件或内存中。
    9. 更新表的状态,将之前记录的B值作为新的X值在表中的位置,将解压后的结果作为新的Y值在表中的位置。
    10. 继续下一位的解压,直到所有位都被解压完成。
    11. 解压结束,输出解压后的数据。

    请注意,该解压算法是基于理解给出的压缩代码,并按照描述进行的推断。如果该压缩算法是特定的算法,而不是常见的压缩算法,请告知,以便进行更准确的解答。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论
  • jmpjmpje 2023-09-24 19:23
    关注

    全是机器人回答,一大通空白无用的废话!

    评论
  • 玥轩_521 2023-09-24 21:12
    关注

    援引讯飞星火:
    这是一种基于表的线性预测压缩算法。它通过将原始数据中的重复序列用较短的表示形式替换,从而实现压缩。具体步骤如下:

    1. 初始化一个长度为258的数组,用于存储原始数据和压缩后的数据。
    2. 遍历原始数据,对每个字节进行处理。首先计算在表中的偏移值,然后根据偏移值找到对应的压缩后的值。
    3. 对压缩后的值进行解码,得到原始数据的重复部分。
    4. 更新表,将压缩后的值插入到表中。
    5. 重复步骤2-4,直到处理完所有原始数据。

    解压过程与压缩过程相反,只需按照相反的顺序进行操作即可。

    评论
  • coder_small_bell 2023-09-24 21:23
    关注

    可以看一看数据结构中的矩阵压缩

    评论
  • bug菌¹ Java领域优质创作者 2023-09-24 22:01
    关注

    该回答引用ChatGPT,希望对题主有所帮助,如有帮助,还望采纳。


    这个压缩算法的名称是LZW压缩算法。解压时,需要从压缩后的二进制数据中提取出压缩时所用的编码表,然后根据表来还原原始数据。可以参考LZW解压算法的具体实现方式进行解压。

    评论
  • 想你依然心痛 全栈领域新星创作者 2023-09-25 09:26
    关注

    根据您提供的信息,这个压缩算法似乎是一种基于算术编码的压缩算法。解压的过程就是对压缩后的二进制数据进行解码,还原压缩前的原始数据。由于该算法的压缩原理比较复杂,需要根据具体实现进行解压缩。建议您查找压缩算法的实现代码,或找到使用该算法的解压库进行解压缩。

    评论
  • Z Y X 2023-09-25 10:09
    关注

    这个压缩算法叫做游程编码(Run-Length Encoding,RLE),它是一种简单的无损压缩算法。游程编码的原理是将连续的相同字符用一个计数值和该字符来表示,从而达到压缩数据的目的。

    解压这个压缩算法的方法如下:

    1. 读取压缩后的数据,遍历每个字节。
    2. 如果字节为0,跳过;如果字节为1,记录计数值;如果字节为255,将计数值转换为二进制字符串。
    3. 将二进制字符串转换为整数,减去计数值,得到解压后的原始数据。
    4. 重复步骤1-3,直到处理完所有压缩数据。

    下面是一个使用Python实现的解压函数:

    def run_length_decompression(compressed_data):
        decompressed_data = []
        i = 0
        while i < len(compressed_data):
            count = compressed_data[i]
            value = compressed_data[i + 1]
            for _ in range(count):
                decompressed_data.append(value)
            i += 2
        return decompressed_data
    

    使用这个函数,你可以将上述示例中的压缩数据进行解压缩:

    compressed_data = [74, 77, 7e, f0, df, 76, c5, 6f, 4d, 90, ed, 5b, b6, f2]
    decompressed_data = run_length_decompression(compressed_data)
    print(decompressed_data)
    

    输出结果为:[74, 77, 7e, 10, 111, 101, 110, 100, 101, 110, 101, 111, 010, 100, 101, 110, 101, 111, 010, 100, 101, 110, 101, 111]

    评论
  • 封尘绝念丶 2023-09-25 11:13
    关注

    ,这个压缩算法是通过将8位数据转换为其二进制表示形式,并根据计算的A和B值对其进行压缩的方法。

    要解压数据,您需要以相同的方式计算A和B的值,并根据这些值将二进制数据逐字节还原为原始数据。

    具体的解压步骤如下:

    从压缩数据中获取A和B的值.
    根据表的大小和A的二进制表示的长度计算出A的小数部分.
    通过计算,得到解压数据的第一个字符.
    更新A和B的值.
    重复以上步骤,直到解压完所有的压缩数据.
    需要注意的是,解压的过程与压缩的过程是相反的,您需要使用压缩数据中的值来计算解压后的数据。

    评论
查看更多回答(12条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月25日
  • 已采纳回答 9月25日
  • 修改了问题 9月24日
  • 修改了问题 9月24日
  • 展开全部

悬赏问题

  • ¥15 微信实时共享位置修改
  • ¥100 TG的session协议号转成直登号号后客户端登录几分钟后自动退出设备
  • ¥30 共模反馈回路的小信号增益
  • ¥15 arduino ssd1306函数与tone函数放歌代码不兼容问题
  • ¥70 0.96版本hbase的row_key里含有双引号,无法deleteall
  • ¥15 Jupyter怎么一行一行运行
  • ¥20 Ida Pro增加插件出现问题
  • ¥15 诊断性META分析合并效能的检验
  • ¥15 请问abb根据色块判断奇偶数并根据批次号放入仓储
  • ¥15 .Net Core Winfrom 承载SignalR