【问题标题】:Decompress .Z files (LZW Compression) in C#在 C# 中解压缩 .Z 文件(LZW 压缩)
【发布时间】:2022-08-18 14:53:40
【问题描述】:

我希望在 C# 中实现 Rosetta Code LZSW 解压缩方法,我需要一些帮助。原始代码可在此处获得:http://rosettacode.org/wiki/LZW_compression#C.23

我只关注解压缩方法,因为我“只是”(如果只是)想在 .NET 6 的 C# 程序中解压缩 .Z 文件。

我希望我的版本将一个 byte[] 作为输入并返回一个 byte[](因为我正在从文件中读取 .ReadAllBytes() 并希望使用解压缩的结果创建一个新文件)。

我的问题来自这样一个事实,即在 C# 中,字符是 16 位(2 个字节)而不是 8 位(1 个字节)。这真的让我很头疼,因为(在我看来)这意味着每个字符应该由两个字节表示。在 Rosetta Code 的代码中,创建的初始字典仅包含 0 -> 255 的整数键,表示最多 1 个字节,而不是两个。我在想这是否是他们实施中的错误?你怎么看?您将如何将此算法转换为带有签名的方法:byte[] Decompress(byte[])

谢谢

  • 是否有某些原因您不想使用 System.IO.Compression 类?
  • 为什么chars 不是 8 位很重要?这就是byte 的用途!即使在 C 语言中,char 也不能保证是 8 位(至少,在我做一些 DSP 工作时不是这样,而且一切都是 16 位的,包括字符!)。
  • @SteveTodd 只不过这些类不支持 lzw 编码。

标签: c# .net compression lzw


【解决方案1】:

不,没有错误。不,您不会将算法转换为适用于 16 位值。压缩代码对字节序列进行操作。您的字符串首先需要转换为字节序列,例如到 UTF-8,例如byte[] bs = Encoding.UTF8.GetBytes(str);。 UTF-8 将是正确的选择,因为该编码为压缩器提供了最佳的压缩效果。任何您压缩的数据首先需要以允许反转转换的方式序列化为字节序列(如果它不是字节)。

由于你在解压,有人将字符编码成一个字节序列,所以你需要先找出它们做了什么。它可能只是一个 ASCII 字符序列,每个字符已经是一个字节。然后你会使用System.Text.Encoding.ASCII.GetString(bs); 来制作一个字符串。

【讨论】:

  • 在压缩之前必须将数据转换为字节序列的说法是错误的。压缩算法通常适用于符号, 这些可以是任何东西,包括字符。最多实现仅适用于字节,但这是一个实现问题。完全有可能实现 LZW 直接对浮点数或双精度数进行操作。
  • @jonash 我不是在说你可以做。我说的是实际的、现成的、无损的压缩器。它们都在字节上工作。
【解决方案2】:

在压缩数据时,我们通常谈论的序列符号.在这种情况下,符号可能是一个字节、一个字符或完全不同的东西。

您的示例显然使用字符作为它的符号,但不应该有任何真正的问题只是用字节替换它。更困难的部分将是它使用字符串来表示字符序列.您将需要提供以下功能的字节序列的等效表示:

  • 串联/附加
  • 平等
  • GetHashCode(用于性能)
  • 不变性(即附加一个字节应该产生一个新序列,而不是修改现有序列)

请注意,LZW 实现必须就某些特定的事情达成一致才能兼容,因此实现发布的示例可能允许也可能不允许您解码使用其他实现编码的 .Z 文件。如果您的目标是解码实际文件,您可能会更幸运地向software recommendations 询问预先存在的解压缩库。

【讨论】:

    猜你喜欢
    • 2021-02-09
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多