Java DeflaterInputStream () в ZlibInflation

В настоящее время я работаю над проектом, который включает сжатие и шифрование в Java, а также дешифрование и инфляцию в C ++.

До того, над чем я работал, мы создавали сжатые файлы, используя ZipOutputStream в Java. Эти файлы будут раздувать zlib в C ++ просто отлично, используя код zpipe.c, приведенный в качестве примера на ZLib. Нашим последним изменением было сжатие этих файлов и их шифрование перед сохранением в родительском zip-архиве. При этом я переключился на использование класса DeflaterInputStream в Java для произвольного сжатия байтов до тех пор, пока мне не хватит для блочного шифра.

При переключении на этот класс «DeflaterInputStream» файлы больше не будут раздуваться с помощью ZLib. Zlib выбрасывает «Z_DATA_ERROR» в поток.

Для проверки до сих пор я убедился, что криптологическая логика действительна. Я могу просто накачать файлы в Java, используя класс «Inflater». Оба класса инфлатера начинаются с одного расшифрованного блока. Ex. Я убедился, что первый блок, который выходит из шифра, одинаков как для Java, так и для C ++. Мне кажется, что DeflaterInputStream не выводит истинный формат выкачки? Я не уверен.

РЕДАКТИРОВАТЬ: чтобы уточнить мою конкретную реализацию
Пример псевдо-кода:

Java (Работа с zpipe)

FileOutputStream dest = new FileOutputStream("zipfile.zip");
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));

ZipEntry entry = new ZipEntry("filename");
out.putNextEntry(entry);

FileInputStream fileInputStream = new FileInputStream("file_to_compress");

byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = fileInputStream.read(buf)) > 0) {
out.write(buf, 0, bytesRead);
}
out.closeEntry();
out.close();
fileInputStream.close();

Java (не работает с zpipe)

FileOutputStream dest = new FileOutputStream("zipfile.zip");
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));

DeflaterInputStream deflater = new DeflaterInputStream("file_to_compress");

/* Redacted code to compress file, encrypt, write to file and calculate CRC
Assume encryptedFile is a reference to the result of this process */ZipEntry entry = new ZipEntry("filename");
entry.setCrc32(encryptedFile.getCrc32());
entry.setCompressedSize(encryptedFile.getLength());
entry.setMethod(ZipEntry.STORED); /* Should not try to compress encrypted file*/

out.putNextEntry(entry);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = encryptedFile.read(buf)) > 0) {
out.write(buf, 0, bytesRead);
}
out.closeEntry();
encryptedFile.close();
out.close();

Так что в значительной степени я использую DeflaterInputStream, чтобы сжать фиксированный размер для подачи в шифр, а затем сохранить в архиве. У меня это работает от начала до конца внутри Java, беря результаты DeflaterInputStream и шифра и записывая в файл, затем расшифровывая в буфер открытого текста и используя класс Inflater для обработки этого. Насколько я понимаю, классы Inflater и DeflaterInputStream обрабатывают необработанный поток deflate без учета или добавления какого-либо заголовка архива. Мы используем наш собственный код на C ++ для разбора заголовков архива и всего, что нужно для подачи в zpipe.

Я ожидаю, что Zlib / Zpipe сможет обрабатывать необработанный поток, который я создаю с использованием DeflaterInputStream, так же, как если бы я сжимал с использованием универсального объекта ZipEntry / ZipOutputStream.

С тех пор как я попытался использовать DeflaterInputStream, zlib / zpipe выдает ошибку при попытке прочитать поток.

ОБНОВИТЬ

Для устранения неполадок я сделал следующее:

Сохранен необработанный вывод DeflaterInputStream, сжимающего файл.

Использовал тот же файл в паре ZipOutputStream / ZipEntry для создания сжатого архива zip.

Использовал Hex Editor для удаления локальных заголовков файлов и центрального каталога архива, оставляя только необработанный поток deflate.

Запустил отредактированный файл (raw deflate stream) через zpipe: сработало

Запустил вывод DeflaterInputStream через zpipe: не работает

ОБНОВЛЕНИЕ 2

Так что я просто сравнил результаты двух.
DeflaterInputStream дает мне два дополнительных байта в начале потока. Я понятия не имею, что это за байты. Если я пропущу их с помощью fseek (), файл распаковывается очень хорошо. Значения 0x78 0x9C этих загадочных байтов …

ОБНОВЛЕНИЕ 3

Я ссылался на RFC 1951 на протяжении всего этого процесса, однако, похоже, что магические два байта взяты из RFC 1950. Было введено в заблуждение названием «DeflaterInputStream».

Инициализация DeflaterInputStream с помощью следующего решает мою проблему:

Deflater def = new Deflater(Deflater.DEFAULT_COMPRESSION,true);
DeflaterInputStream defIfs = new DeflaterInputStream(ifs,def);

Большое спасибо Марку за внимание к этому вопросу! Zlib — прекрасный проект.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector