将Java的DEFLATE算法移植到C#

问题描述 投票:-2回答:1

我们需要使用DEFLATE算法解压缩Java系统创建的一些数据。我们无法控制。

虽然我们不知道确切的变体,但我们可以使用以下Java代码解压缩发送给我们的数据:

 public static String inflateBase64(String base64)
    {
        try (Reader reader = new InputStreamReader(
                new InflaterInputStream(
                        new ByteArrayInputStream(
                                Base64.getDecoder().decode(base64)))))
        {
            StringWriter sw = new StringWriter();
            char[] chars = new char[1024];
            for (int len; (len = reader.read(chars)) > 0; )
                sw.write(chars, 0, len);
            return sw.toString();
        }
        catch (IOException e)
        {
            System.err.println(e.getMessage());
            return "";
        }
    }

不幸的是,我们的生态系统基于C#。我们目前正在使用Process对象来攻击Java程序,但从性能的角度来看,这显然是次优的,所以我们希望尽可能将上面的代码移植到C#。

一些示例输入和输出:

>java -cp . Deflate -c "Pack my box with five dozen liquor jugs."
eJwLSEzOVsitVEjKr1AozyzJUEjLLEtVSMmvSs1TyMksLM0vUsgqTS/WAwAm/w6Y
>java -cp . Deflate -d eJwLSEzOVsitVEjKr1AozyzJUEjLLEtVSMmvSs1TyMksLM0vUsgqTS/WAwAm/w6Y
Pack my box with five dozen liquor jugs.
>

我们被告知Java系统符合RFC 1951所以我们已经查看了很多库,但它们似乎都没有正确地解压缩数据(如果有的话)。一个例子是DotNetZip:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ionic.Zlib;

namespace Decomp
{
    class Program
    {
        static void Main(string[] args)
        {                        
            // Deflate

            String start = "Pack my box with five dozen liquor jugs.";

            var x = DeflateStream.CompressString(start);
            var res1 = Convert.ToBase64String(x, 0, x.Length);

            // Inflate 

            //String source = "eJwLSEzOVsitVEjKr1AozyzJUEjLLEtVSMmvSs1TyMksLM0vUsgqTS/WAwAm/w6Y"; // *** FAILS ***
            String source = "C0hMzlbIrVRIyq9QKM8syVBIyyxLVUjJr0rNU8jJLCzNL1LIKk0v1gMA"; 

            var part1 = Convert.FromBase64String(source);            

            var res2 =  DeflateStream.UncompressString(part1);
        }
    }
}

这根据文档实现了RFC 1951,但没有正确解密字符串(可能是由于实现之间的微妙算法差异)。

从开发的角度来看,我们可以理解我们需要编写的确切变体。是否有任何标题信息或在线工具可用于提供初始转向?感觉就像我们在这里的黑暗中拍摄一样。

java c# compression deflate
1个回答
3
投票

https://www.nuget.org/packages/ICSharpCode.SharpZipLib.dll/

using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using System;
using System.IO;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = "Pack my box with five dozen liquor jugs.";

            string encoded = Encode(input);
            string decoded = Decode(encoded);

            Console.WriteLine($"Input: {input}");
            Console.WriteLine($"Encoded: {encoded}");
            Console.WriteLine($"Decoded: {decoded}");

            Console.ReadKey(true);
        }

        static string Encode(string text)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(text);

            using (MemoryStream inms = new MemoryStream(bytes))
            {
                using (MemoryStream outms = new MemoryStream())
                {
                    using (DeflaterOutputStream dos = new DeflaterOutputStream(outms))
                    {
                        inms.CopyTo(dos);

                        dos.Finish();

                        byte[] encoded = outms.ToArray();                                              

                        return Convert.ToBase64String(encoded);
                    }
                }
            }
        }

        static string Decode(string base64)
        {
            byte[] bytes = Convert.FromBase64String(base64);

            using (MemoryStream ms = new MemoryStream(bytes))
            {
                using (InflaterInputStream iis = new InflaterInputStream(ms))
                {
                    using (StreamReader sr = new StreamReader(iis))
                    {
                        return sr.ReadToEnd();
                    }
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.