Репликация c# алгоритма декомпрессии в Ruby - PullRequest
1 голос
/ 29 января 2020

Я имею дело с внешним API (написанным на c#), который возвращает сжатую GZIP-строку в качестве ввода. Мой потребитель написан на Ruby, и мне нужно написать логику декомпрессии c на Ruby. Они предоставили мне рабочий c# фрагмент, который успешно распаковывает строку. У меня проблемы с репликацией того же в Ruby. Ответ API закодирован в Base64 и должен быть декодирован перед передачей в декомпрессор. Мне удалось повторить этот шаг в Ruby.

Вот сжатая строка в кодировке Base64, с которой я работаю

Input
DcixCYBADAXQVUJqwd5OFDsrJzjkIwG9kyQniDiZhSO5gtc93ve8F/fwIKtxc/HkwXMRD2WygiseYRYWlOuyedqgJEYxOSkWMYfW1KOdXQ6QRDpTVtpDxMr3/QM=

Expected Output
{"Details":{"Status":"Failure","Message":"Customer is not register/ DeActive in your panel"}}

C# code

using System;
using System.IO;
using System.Text;
using System.IO.Compression;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string strResult = "";
            byte[] input = Convert.FromBase64String("DcixCYBADAXQVUJqwd5OFDsrJzjkIwG9kyQniDiZhSO5gtc93ve8F/fwIKtxc/HkwXMRD2WygiseYRYWlOuyedqgJEYxOSkWMYfW1KOdXQ6QRDpTVtpDxMr3/QM=");
            Console.WriteLine("   {0}\n", BitConverter.ToString(input)); 
            using(MemoryStream inputStream = new MemoryStream(input)) {  
                    using(DeflateStream gzip = new DeflateStream(inputStream, CompressionMode.Decompress)) {
                        using(StreamReader reader = new StreamReader(gzip, System.Text.Encoding.UTF8)) {
                            strResult = reader.ReadToEnd();
                            Console.WriteLine(strResult);
                        }

                    }
                }
            }

    }
}

Ruby код

require 'base64'
require 'stringio'
require 'zlib'
require 'open-uri'

def decompress(compressedstring)
    byte_array = Base64.decode64(compressedstring).unpack("C*")
    response = Zlib::Inflate.inflate(byte_array.join(""))
end

В данный момент код ruby выдает следующую ошибку

Zlib::DataError: incorrect header check
    from (irb):22:in `inflate'
    from (irb):22
    from /Users/gendalf/.rvm/rubies/ruby-1.9.3-head/bin/irb:12:in `<main>'

============= ==============================

Обновление

I удалось добиться некоторого прогресса с помощью следующего Ruby кода

require 'base64'
require 'stringio'
require 'zlib'
require 'open-uri'

def decompress(compressedstring)
    decoded_string = Base64.decode64(compressedstring)
    zlib = Zlib::Inflate.new(-Zlib::MAX_WBITS);
    zlib.inflate(decoded_string)
end

decompress("DcixCYBADAXQVUJqwd5OFDsrJzjkIwG9kyQniDiZhSO5gtc93ve8F/fwIKtxc/HkwXMRD2WygiseYRYWlOuyedqgJEYxOSkWMYfW1KOdXQ6QRDpTVtpDxMr3/QM=")

Вывод для того же выглядит так:

"\xEF\xBB\xBF{\"Details\":{\"Status\":\"Failure\",\"Message\":\"Customer is not register/ DeActive in your panel\"}}" 

Как уже упоминалось в комментариях, я могу отбросить EFBBBF (UTF-8 BOM: en.wikipedia.org / wiki / Byte_order_mark ), а затем проанализировать оставшуюся часть JSON. Я думаю, что это решает мою проблему. Было бы здорово, если бы кто-то мог подробно объяснить, что здесь происходит, чтобы помочь другим в будущем. У меня это работает, но я не очень уверен в фактической работе.

...