मेरे पास बेस 64 स्ट्रिंग qsZhqyXY0rTEnOLUWgAAAAD//w== है।
यह JSON प्रारूप में एक UTF8 स्ट्रिंग का प्रतिनिधित्व करता है (मेरा मानना ​​​​है) zlib का उपयोग करके संकुचित। मैं JSON की सटीक सामग्री नहीं जानता।

मैं पहले इस स्ट्रिंग को बाइट्स में परिवर्तित करता हूं:

var bytes = Convert.FromBase64String(base64string);
foreach (var b in bytes) Console.Write($"{b:x2} ");
// aa c6 61 ab 25 d8 d2 b4 c4 9c e2 d4 5a 00 00 00 00 ff ff

इसके अंत में मानक 00 00 ff ff है, लेकिन मुझे पता है कि कोई भी zlib जादू शीर्षलेख नहीं है:

  • 78 01 कम संपीड़न
  • 78 9c डिफ़ॉल्ट संपीड़न
  • 78 da सर्वोत्तम संपीड़न

आम तौर पर, मेरी समझ यह है कि DeflateStream के साथ काम करते समय आपको संपीड़न प्रकार निर्दिष्ट करने वाले पहले दो बाइट्स को हटाना होगा। इस बाइट सरणी को डीकंप्रेस करने के लिए मेरी विधि यहां दी गई है, यह हेडर को हटा देता है, हालांकि हेडर को हटाने पर भी यह विफल हो जाता है।

public static byte[] InflateByteArray(byte[] bytes)
{
    var outputStream = new MemoryStream();
    MemoryStream inputStream = new MemoryStream(bytes, 2, bytes.Length - 2); 
    
    using var deflateStream = new DeflateStream(inputStream, CompressionMode.Decompress);
    deflateStream.CopyTo(outputStream); // exception here
    
    return outputStream.ToArray();
}

मुझे एक System.IO.InvalidDataException संदेश के साथ मिलता है 'संग्रह प्रविष्टि को एक असमर्थित संपीड़न विधि का उपयोग करके संकुचित किया गया था।' जब मैं उपरोक्त बाइट सरणी पर इस विधि को चलाता हूं।

ऐसा क्यों हो रहा है? यह संदेश किस संपीड़न विधि का उपयोग कर रहा है?

1
doliphin 17 फरवरी 2021, 18:50

2 जवाब

सबसे बढ़िया उत्तर

यह एक अपस्फीति धारा के मध्य से अपस्फीति डेटा का एक छोटा सा टुकड़ा है। इससे पहले कम से कम अपस्फीति धारा के बिना यह आपके लिए अच्छा नहीं है। इसका एक अपस्फीति "विघटन" देता है:

fixed
literal '{
match 23 118
literal '9
match 5 117
literal 'false}
end
stored
end

वह match 23 118 इस छोटे से डिफ्लेट स्निपेट में उपलब्ध कराए गए डेटा से पहले वे से बाइट्स कॉपी करने के लिए कहता है। (117 बाइट्स पहले।) दूसरे match के लिए समान। डीकंप्रेस्ड डेटा एक {, अतीत से 23 बाइट्स जिसे आप नहीं जानते, एक 9, पांच और बाइट्स जिन्हें आप नहीं जानते हैं, और false} हैं।

इनमें से कोई भी डिफ्लेट ब्लॉक अंतिम ब्लॉक के रूप में चिह्नित नहीं है, इसलिए इस स्निपेट के बाद अधिक डिफ्लेट डेटा है।

अंत में खाली संग्रहीत ब्लॉक जिसे आप "मानक 00 00 ff ff अंत में" के रूप में संदर्भित करते हैं, वास्तव में मानक नहीं है। यही वह है जो तब डाला जाता है जब प्रत्येक टुकड़े को बाइट सीमा तक लाने के लिए, ट्रांसमिशन के लिए किसी कारण से एक डिफ्लेट स्ट्रीम को छोटे टुकड़ों में तोड़ दिया जाता है। आम तौर पर डिफ्लेट ब्लॉक किसी भी बिट स्थान पर शुरू हो सकते हैं। आप उन्हें सामान्य रूप से संपीड़ित डिफ्लेट स्ट्रीम में नहीं पाएंगे।

4
Mark Adler 18 फरवरी 2021, 01:54

निम्नलिखित का प्रयास करें:

           string input = "aa c6 61 ab 25 d8 d2 b4 c4 9c e2 d4 5a 00 00 00 00 ff ff";
            byte[] bytes = input.Split(new char[] { ' ' }).Select(x => byte.Parse(x, System.Globalization.NumberStyles.HexNumber)).ToArray();
            MemoryStream ms = new MemoryStream(bytes);
            ms.Position = 0;
            System.IO.Compression.DeflateStream gzip = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Decompress);
            List<byte> uncompressed = new List<byte>();
            int bytesRead = 0;
            do
            {
                byte[] chunk = new byte[1000];
                bytesRead = gzip.Read(chunk, 0, 1000);
                uncompressed.AddRange(chunk.ToList().GetRange(0,bytesRead));
            } while (bytesRead == 1000);
1
jdweng 17 फरवरी 2021, 20:30