压缩在Ruby中Gzip已串(Compress Gzip string in Ruby)

2019-07-17 15:34发布

我怎么会写来压缩不包含头文件Gzip已串的方法,并把它压缩到它到底是在我已经解压的方式。 原始压缩在C#完成,并且我使用以下方法中的Ruby充气:

编辑:基本上, 我想匹配的放气的方法来此充气:

def inflate(string)
    zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
    buf = zstream.inflate(string)
    zstream.finish
    zstream.close
    buf
end

前解压缩,该字符串是:

"5\x891\n\xC30\x10\x04{\xBDb\xEB\xE0F&\x81\xA4\xCA3\xDC\xA81\xD2\x1A]\xA1\x13\xB1.\x100\xFEF\xDE\e\x19\x9Cb\x99Yf\xCA\xB3A\x1A,\x13\xB1\x96R\x15I\x96\x85+5\x12\xA2=\xF4:\xAFb\xB9\xD0$\xA2\xF1\xF5>\xDA\xD3\xB9\x9A\xA8f\xFC\xD8\xE6\xFD\x00\x7F\xEB{\f!Uk{\xCF,\x91\xDC\x1C\x10J\xC4\xF7z\xCA\xE8p9\xF8\xFF\xF7\x93\xDEw\xD9\x7F"

而使用膨胀解压后,它是:

    "What is the common difference in this arithmetic sequence?\n\n\\indenttext{11, 15, 19,\\dots}\n\n\\emcee{\n  \\mc \x964\n  \\mc 2\n *\\mc 4\n  \\mc 8\n  \\mc 11\n  }"

我试图创建多个放气的方法,但是没有人能得到它回到原来的。 谢谢你的帮助!

编辑:原来的压缩是在.NET 2.0做使用以下

byte[] compressedStringBytes = CompressGzipString(String);

和CompressGzipString作用:

MemoryStream compressed = new MemoryStream();
DeflaterOutputStream zosCompressed = new DeflaterOutputStream(compressed, new Deflater(Deflater.BEST_COMPRESSION, true));
zosCompressed.Write(data, 0, data.Length);

如果这是不可能得到它的确切原来,这将是最规范的压缩,我指的是一般的,这将是能够以同样的方式,原来是被解压?

Answer 1:

不同压缩机,不同版本的相同压缩机,或相同的版本相同的压缩机的具有不同设置的,可以并经常会产生对相同的输入不同的输出,即使它们都使用相同的压缩数据的格式(例如放气)。 保证的唯一的事情是,当你解压缩,你得到完全回到您开始使用同样的事情。 事实上,这真的所有你需要保证。 你为什么要一模一样的压缩物流?

正如罗恩Warholic注意,你甚至不想之前找回从.NET的破放气实现压缩输出给.NET 4.5。 由于.NET 2.0中使用自己独特的,坏了,放气实现,你不能用红宝石复制它,它使用zlib的。

另外,作为由Ron Warholic,红宝石和.NET 4.5或更高版本都使用zlib的注意,所以必须既产生具有选择的相同的压缩级别相同的压缩输出。 虽然这不是永远放心,因为ZLIB的新版本可能会产生不同的输出,与红宝石的一个或而其他没有.NET可能会更新它。 此外,如下所述,您不必在使用.NET的类的压缩级别直接控制。

如果这是不可能得到它的确切原来,这将是最规范的压缩,我指的是一般的,这将是能够以同样的方式,原来是被解压?

任何正确执行无损压缩和解压缩都会有这个属性。 你总是会回来的确切原来,无论压缩数据可能会有何不同。 没有“最规范的压缩”。

Zlib::Inflate.new(-Zlib::MAX_WBITS)期待原始放气流,无头或尾。 所以,你需要产生在C#的一面。

这不是从透明.NET文档的是否DeflateStream类压缩以deflate格式或ZLIB格式(其中后者是与zlib的包装deflate格式,由两个前缀字节和用于数据的完整性检查4个后缀字节)。 如果压缩到deflate格式,那么这将是与兼容Zlib::Inflate.new(-Zlib::MAX_WBITS) 如果压缩到zlib的格式,那么这将是兼容Zlib::Inflate.new(Zlib::MAX_WBITS)即不带负号)。 或者你可以删除的前两个字节和最后四个字节要回放气流。

DeflateStream在.NET类中,它的一个有点古怪CompressionLevel是一个enum ,只有三个选择,而不是由zlib的(0..9)提供的十级。 这三个选项是OptimalFastest ,和NoCompression 。 最后必须为0,第一个可能是9,和中间的一个可能是1或3。在任何情况下,有一个默认的压缩级别别无选择! 这一水平(6)是压缩与时间的很好的平衡。

您可能要考虑使用DotNetZip代替。 它提供了一个完整的接口为zlib,这样你可以指定你想要做什么,并且知道会发生什么。



Answer 2:

这取决于它是如何在C#真的压缩; 之前.NET 4.5的System.IO.DeflateStream/GZipStream类在C#中使用的Microsoft实现DEFLATE的,从zlib的显著差异(这意味着你可能无法与zlib的容易效仿)。 这是在几乎所有情况差得多所以在.NET 4.5,他们与zlib的应该是能够匹配,你可以在Ruby中做什么取代了它。

如果你知道是什么版本的C#生成的字符串,你可以决定你是否能回到原来的字节。 如果它与.NET 4.5生成的,你应该能够做一个标准的放气以相同的设置,以获得相同的字节。



文章来源: Compress Gzip string in Ruby