• Как сжать и закодировать данные так, чтобы их можно было отправить в теле запроса на сервер?

    Vindicar
    @Vindicar
    RTFM!
    У тебя различие появляется в том, что gzip.compress() даёт не тот же результат, что был подан в gzip.decompress().
    Видимо, разные реализации алгоритма gzip. Но если данные успешно разжимаются, то не всё ли равно?

    EDIT: я посмотрел инфу о заголовке Gzip. Создать идентичный заголовок несложно, но проблема идёт дальше: сами данные непохожи. Я раскопал, как получить "голый" deflate-поток без заголовков, и попытался сравнить его с тем, что идёт после gzip-заголовка в твоих данных. В твоём случае заголовок минималистичный, поэтому занимает всего 10 байт, а дальше идёт deflate-поток. Он успешно разжимается в те же данные, которые даёт gzip, так что я вроде не ошибся.

    Но попытка перебора вариантов сжатия так, чтобы получить хоть что-то похожее, результатов не дала.
    Вот мой код, увы, он выводит Match not found.
    import binascii, gzip, zlib, sys
    
    def deflate(data, compresslevel=9, strategy=0, wbits=zlib.MAX_WBITS, memlevel=zlib.DEF_MEM_LEVEL):
        compress = zlib.compressobj(
                compresslevel,        # level: 0-9
                zlib.DEFLATED,        # method: must be DEFLATED
                -wbits,               # window size in bits:
                                      #   -15..-8: negate, suppress header
                                      #   8..15: normal
                                      #   16..30: subtract 16, gzip header
                memlevel,             # mem level: 1..8/9
                strategy              # strategy:
                                      #   0 = Z_DEFAULT_STRATEGY
                                      #   1 = Z_FILTERED
                                      #   2 = Z_HUFFMAN_ONLY
                                      #   3 = Z_RLE
                                      #   4 = Z_FIXED
        )
        deflated = compress.compress(data)
        deflated += compress.flush()
        return deflated
    
    def inflate(data):
        decompress = zlib.decompressobj(
                -zlib.MAX_WBITS  # see above
        )
        inflated = decompress.decompress(data)
        inflated += decompress.flush()
        return inflated
    
    
    input_data = b"H4sIAAAAAAAA_2SNvU7EMBAG32V7To7txMleB-JKWugsc-wllhI78k8iQLw7sgPVdauZHX0GFX5H7BHMumpnFoJzRIGw03u5muYwG4VovStIIaiT4OLE6gNDuE7GOZq1_SiEdwiZ2wf59Rjy8-vLdnm67Ref_e1t_BxrI2uTtMlp8qF2FlkxLcI1h0Au6RzpX_VStQ1X8li3iZY_IQbVDl3HWX-OOCBEmuf76ucXAAD__wEAAP__grfYVeYAAAA"
    gzipped_data = binascii.a2b_base64(input_data.replace(b"_", b"/").replace(b"-", b"+") + b"=")
    raw_data = gzip.decompress(gzipped_data)
    print('RAW', raw_data)
    
    deflate_stream = gzipped_data[10:]
    inflated = inflate(deflate_stream)
    print('DEFLATED DATA', deflate_stream)
    print('RESTORED DATA', inflated)
    print('Restored data matches original:', inflated == raw_data)
    
    for level in range(1, 10):
        for strategy in range(0, 5):
            for wbits in range(9, 16):
                for memlevel in range(1, 10):
                    test = deflate(raw_data, level, strategy, wbits, memlevel)
                    if deflate_stream.startswith(test) or test.startswith(deflate_stream):
                        print(level, strategy, wbits, memlevel)
                        sys.exit(0)
    else:
        print('No match found')
    Ответ написан
    1 комментарий