Я взаимодействия с сервером, который требует, чтобы данные, посланные к нему сжат с выкачивает алгоритма (кодирование Хаффмана + LZ77), а также передает данные, которые мне нужно Накачайте.Python: надуть и выкачать реализации
Я знаю, что Python включает в себя Zlib, и что библиотеки C в Zlib обращений в службу поддержки на Накачайте и выкачивает, но они, по-видимому, не обеспечиваются модулем Python Zlib. Это действительно обеспечивает Сжать и Decompress, но когда я делаю вызов, такие как:
result_data = zlib.decompress(base64_decoded_compressed_string)
Я получаю следующее сообщение об ошибке:
Error -3 while decompressing data: incorrect header check
Gzip не делает не лучше; при выполнении вызова, такие как:
result_data = gzip.GzipFile(fileobj = StringIO.StringIO(base64_decoded_compressed_string)).read()
Я получаю сообщение об ошибке:
IOError: Not a gzipped file
, который имеет смысл, поскольку данные являются Дефлированные файл не является истинным сжат GZIP файл.
Теперь я знаю, что есть выкачивает реализация доступна (Pyflate), но я не знаю, из реализации Inflate.
Кажется, что есть несколько вариантов:
- Найти существующую реализацию (идеал) Накачайте и Deflate в Python
- Написать свое собственное расширение Python к ZLIB с библиотека, которая включает в себя Inflate и Deflate
- Позвоните еще что-нибудь, что может быть выполненный из командной строки (например, сценарий Ruby, начиная с Inflate/Deflate звонки в zlib полностью завернуты в Ruby)
- ?
Я ищу решение, но без решения я буду благодарен за идеи, конструктивные мнения и идеи.
Дополнительная информация: Результат сдувания (и кодирования) строку следует, для целей, мне нужно, дают тот же результат, как и следующий фрагмент кода С #, где входной параметр представляет собой массив UTF байт соответствующие данным для сжатия:
public static string DeflateAndEncodeBase64(byte[] data)
{
if (null == data || data.Length < 1) return null;
string compressedBase64 = "";
//write into a new memory stream wrapped by a deflate stream
using (MemoryStream ms = new MemoryStream())
{
using (DeflateStream deflateStream = new DeflateStream(ms, CompressionMode.Compress, true))
{
//write byte buffer into memorystream
deflateStream.Write(data, 0, data.Length);
deflateStream.Close();
//rewind memory stream and write to base 64 string
byte[] compressedBytes = new byte[ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(compressedBytes, 0, (int)ms.Length);
compressedBase64 = Convert.ToBase64String(compressedBytes);
}
}
return compressedBase64;
}
Выполнение этого.NET код строки «выкачать и закодировать меня» дает результат
7b0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP358Hz8iZvl5mbV5mi1nab6cVrM8XeT/Dw==
Когда «выкачать и закодировать меня» запускается через Python Zlib.compress(), а затем в кодировке base64, результат «eJxLSU3LSSxJVUjMS1FIzUvOT0lVyE0FAFXHB6k =» ,
Понятно, что zlib.compress() не является реализацией того же алгоритма, что и стандартный алгоритм Deflate.
Дополнительная информация:
Первые 2 байта .NET выкачать данные ("7b0HY ..."), после декодирования B64 являются 0xEDBD, что не соответствует данным Gzip (0x1f8b), BZip2 (0x425A) или Zlib (0x789C).
Первые 2 байта сжатых данных Python («eJxLS ...»), после декодирования b64 - 0x789C. Это заголовок Zlib.
решаемые
Для обработки сырой Deflate и раздувать, без заголовка и контрольной суммы, следующие вещи, необходимые для произойти:
На выкачать/компресса: полоса первые два байта (заголовка) и последние четыре байта (контрольная сумма).
Надувание/распаковка: есть второй аргумент для размера окна. Если это значение отрицательное, оно подавляет заголовки. вот мои методы в настоящее время, в том числе кодирования base64/декодирования - и работают правильно:
import zlib
import base64
def decode_base64_and_inflate(b64string):
decoded_data = base64.b64decode(b64string)
return zlib.decompress(decoded_data , -15)
def deflate_and_base64_encode(string_val):
zlibbed_str = zlib.compress(string_val)
compressed_string = zlibbed_str[2:-4]
return base64.b64encode(compressed_string)
+1 Спасибо за дополнительную информацию. – Demi
@John Machin: Чтобы ответить на ваше первое наблюдение ... результат будет только дольше в случае более коротких строк (header? Padding?). Когда я подаю 161 байт данных для дефляции, до кодировки base64 результат составляет 126 байтов. – Demi
@John Machin: Отличная информация и информация. Явная подпись используемого дефлатера - это одна с двумя параметрами, с nowrap == true. Я использовал ваш пример однострочного дефлатера, и он хорошо накапливается в .NET и Java, несмотря на то, что он отличается от значения, вызванного дефляцией с библиотеками на этих языках. Отлично. Теперь я работаю над инфляцией - принимая дефлированные данные, созданные Java или .NET, и добавляя контрольную сумму adler32 и заголовок zlib, чтобы увидеть, могу ли я заставить Python хорошо ее использовать. Я дам вам знать, как это происходит. – Demi