Как правильно сжать строку, чтобы PHP мог распаковывать?
Я попробовал это:
public static byte[] compress(String string) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream(string.length());
DeflaterOutputStream gos = new DeflaterOutputStream(os);
// ALSO TRIED GZOutputStream, same results!
gos.write(string.getBytes());
gos.close();
byte[] compressed = os.toByteArray();
os.close();
return compressed;
}
Но PHP не распознает вывод как допустимую сжатую строку GZip …
Проблема, кажется, в некоторых верхних и нижних колонтитулах, добавляемых Android …
Например, когда я сжимаю something
слово через PHP с gzcompress
Я получил такие же результаты, как с Android, но не достаточно, поэтому PHP мог читать это:
something
(HEX DUMP):
Android: 1f8b08000000000000002bcecf4d2dc9c8cc4b0700
fb31da0909000000
PHP: 789c2bcecf4d2dc9c8cc4b0700
134703cf
Самое странное, что, изменяя GZOutputStream
в DeflaterOutputStream
это исправило проблему с something
словом, но проблема все еще появляется с более длинными строками …
PS. Удаление заголовка 10 символов из данных, сгенерированных Android, совсем не помогает.
РЕДАКТИРОВАТЬЯ пытался распаковать его в PHP с:
gzdecode()
— эта функция не существует в стандартном Debian PHP5gzdecompress()
— не работаетИ некоторые функции для подражания gzdecode()
из комментариев сайта PHP, которые на самом деле мало что делают.
Все выше, с удалением первых 10 байтов и оставлением их.
PS2. Я пробовал каждое решение из Stack Overflow и других источников, но ничего не получилось. Это не дубликат.
РЕДАКТИРОВАТЬ 2 (БИНАРНЫЙ ДАМП): Пример данных, созданных с помощью Android, которые не могут быть распакованы gzuncompress()
или же pseudo-gzdecode()
функции от PHP.NET
: data.compressed.
Это должен быть какой-то JSON после распаковки.
Данные Android, которые начинаются с 1f8b
это поток gzip. В php вы используете gzdecode()
для этого. gzencode()
на php делает потоки gzip.
Данные php, которые начинаются с 789c
это поток ZLIB. Ты использовал gzcompress()
чтобы сделать это, и вы бы использовали gzuncompress()
расшифровать его.
Сжатые данные, содержащиеся в обоих этих потоках, начиная с 2bce
это необработанные данные Ты можешь использовать gzinflate()
расшифровать, что если вам довелось сделать это где-то, и вы можете использовать gzdeflate()
генерировать сырой дефлят.
Просто разглагольствовать, gzencode()
, gzcompress()
, а также gzdeflate()
являются одними из самых вводящих в заблуждение имен функций, когда-либо придуманных, поскольку только одно из них связано с gzip, но все начинаются с gz
и ничего в названии gzcompress()
указывает на zlib.
Обновить:
Данные «EDIT2» по некоторым причинам сжаты вдвое. Сначала он был сжат в формат zlib, а затем поток zlib был сжат в формат gzip. (Хотя gzip не может сжать уже сжатые данные, поэтому он немного больше.)
Вы должны устранить проблему, из-за которой она была вдвойне сжата. Или, если у вас нет контроля над этим, вы можете вдвое распаковать его, сначала удалив заголовок gzip, используя спецификацию RFC 1952, а затем gzinflate()
на необработанных данных, а затем с помощью gzdecompress()
на результат.
Других решений пока нет …