在 C# 中压缩字符串并在 Python 中解压缩

本文关键字:解压缩 Python 串并 字符 压缩 字符串 | 更新日期: 2023-09-27 18:21:55

我正在尝试在C#(.net 4(的客户端程序上压缩一个大字符串,并使用PUT请求将其发送到服务器(django,python 2.7(。理想情况下,我想在两端使用标准库,所以我正在尝试使用 gzip。

我的 C# 代码是:

public static string Compress(string s) {
    var bytes = Encoding.Unicode.GetBytes(s);
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream()) {
        using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
            msi.CopyTo(gs);
        }
        return Convert.ToBase64String(mso.ToArray());
    }
}

python代码是:

s = base64.standard_b64decode(request)
buff = cStringIO.StringIO(s)
with gzip.GzipFile(fileobj=buff) as gz:
    decompressed_data = gz.read()

它几乎可以工作,但输出是:{▯"▯c▯h▯a▯n▯g▯e▯d▯"▯} 当它应该是 {"更改"} 时,即每隔一个字母都是奇怪的。如果我通过执行decompressed_data[::2]来删除所有其他字符,那么它可以工作,但这有点黑客,显然还有其他问题。

我想知道我是否需要对 PUT 请求进行 base64 编码?这是否仅适用于开机自检?

在 C# 中压缩字符串并在 Python 中解压缩

我认为主要问题可能是C#使用UTF-16编码字符串。这可能会产生与您的问题类似的问题。与任何其他编码问题一样,我们在这里可能需要一点运气,但我想你可以通过这样做来解决这个问题:

decompressed_data = gz.read().decode('utf-16')

在那里,decompressed_data应该是Unicode的,您可以将其视为进一步的工作。

更新:这对我有用:

C 夏普

static void Main(string[] args)
    {
        FileStream f = new FileStream("test", FileMode.CreateNew);
        using (StreamWriter w = new StreamWriter(f))
        {
            w.Write(Compress("hello"));
        }
    }
    public static string Compress(string s)
    {
        var bytes = Encoding.Unicode.GetBytes(s);
        using (var msi = new MemoryStream(bytes))
        using (var mso = new MemoryStream())
        {
            using (var gs = new GZipStream(mso, CompressionMode.Compress))
            {
                msi.CopyTo(gs);
            }
            return Convert.ToBase64String(mso.ToArray());
        }
    }

import base64
import cStringIO
import gzip
f = open('test','rb')
s = base64.standard_b64decode(f.read())
buff = cStringIO.StringIO(s)
with gzip.GzipFile(fileobj=buff) as gz:
    decompressed_data = gz.read()
    print decompressed_data.decode('utf-16')

无需decode('utf-16),它打印在控制台中:

>>>h e l l o
有了它,

它做得很好:

>>>hello

祝你好运,希望这有帮助!

它几乎可以工作,但输出是:{▯"▯c▯h▯a▯n▯g▯e▯d▯"▯} 当它应该被{"更改"}

这是因为您正在使用 Encoding.Unicode 将字符串转换为字节以开始。

如果你能告诉Python使用哪种编码,你可以这样做 - 否则你需要在C#端使用与Python期望相匹配的编码。

如果你可以在两边都指定它,我建议使用 UTF-8 而不是 UTF-16。即使您正在压缩,将数据大小减半(在许多情况下(以从:)开始也不会有什么坏处

我也这句话有些怀疑:

buff = cStringIO.StringIO(s)

s实际上不是文本数据 - 它是压缩的二进制数据,应该这样对待。可能没关系 - 只是值得检查是否有更好的方法。