Как расшифровать бинарные данные на Delphi?
Есть рабочее приложение, написанное на Java. Она отправляет запрос на сервер и получает запакованные данные.
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 12 Jan 2023 18:26:21 GMT
Connection: close
Content-Encoding: zip-block
Content-Length: 24640
D @xњіIО+¶іHML±іQЊvvq qЊV°
ВИКМMµURRHN¶U26VиГИС
¶S‚ЌµиС‡(OОЛ¶и V» & D @x.
Полный ответ - Response.txt
При обработке ответа в TidCompressorZlib (Delphi, компонент ZLIB для работы с gzip) получаю ошибку о неправильном формате архивных данных.
Я так понимаю, что при отправке данных происходит еще дополнительно некое их "шифрование".
Я вытащил два блока кода программы на Java:
Модуль CompressedBlockInputStream
import java.io.*; import java.util.zip.DataFormatException; import java.util.zip.Inflater; public class CompressedBlockInputStream extends FilterInputStream { public CompressedBlockInputStream(InputStream inputstream) throws IOException { super(inputstream); inBuf = null; inLength = 0; outBuf = null; outOffs = 0; outLength = 0; inflater = null; inflater = new Inflater(); } protected void readAndDecompress() throws IOException { int i = in.read(); int j = in.read(); int k = in.read(); int l = in.read(); if((i | j | k | l) < 0) throw new EOFException(); inLength = (i << 24) + (j << 16) + (k << 8) + (l << 0); i = in.read(); j = in.read(); k = in.read(); l = in.read(); if((i | j | k | l) < 0) throw new EOFException(); outLength = (i << 24) + (j << 16) + (k << 8) + (l << 0); if(inBuf == null || inLength > inBuf.length) inBuf = new byte[inLength]; if(outBuf == null || outLength > outBuf.length) outBuf = new byte[outLength]; int j1; for(int i1 = 0; i1 < inLength; i1 += j1) { j1 = in.read(inBuf, i1, inLength - i1); if(j1 == -1) throw new EOFException(); } inflater.setInput(inBuf, 0, inLength); try { inflater.inflate(outBuf); } catch(DataFormatException dataformatexception) { throw new IOException((new StringBuilder()).append("Data format exception - ").append(dataformatexception.getMessage()).toString()); } inflater.reset(); outOffs = 0; } public int read() throws IOException { if(outOffs >= outLength) try { readAndDecompress(); } catch(EOFException eofexception) { return -1; } return outBuf[outOffs++] & 0xff; } public int read(byte abyte0[], int i, int j) throws IOException { int k = 0; _L3: if(k >= j) goto _L2; else goto _L1 _L1: if(outOffs < outLength) break MISSING_BLOCK_LABEL_58; try { if(k > 0 && in.available() == 0) return k; } catch(EOFException eofexception) { if(k == 0) k = -1; return k; } readAndDecompress(); int l = Math.min(outLength - outOffs, j - k); System.arraycopy(outBuf, outOffs, abyte0, i + k, l); outOffs += l; k += l; goto _L3 _L2: return k; } public int available() throws IOException { return (outLength - outOffs) + in.available(); } protected byte inBuf[]; protected int inLength; protected byte outBuf[]; protected int outOffs; protected int outLength; protected Inflater inflater; }
Модуль CompressedBlockOutputStream
import java.io.*; import java.util.zip.Deflater; public class CompressedBlockOutputStream extends FilterOutputStream { public CompressedBlockOutputStream(OutputStream outputstream, int i) throws IOException { this(outputstream, i, -1, 0); } public CompressedBlockOutputStream(OutputStream outputstream, int i, int j, int k) throws IOException { super(outputstream); inBuf = null; outBuf = null; len = 0; deflater = null; inBuf = new byte[i]; outBuf = new byte[i + 64]; deflater = new Deflater(j); deflater.setStrategy(k); } protected void compressAndSend() throws IOException { if(len > 0) { deflater.setInput(inBuf, 0, len); deflater.finish(); int i = deflater.deflate(outBuf); out.write(i >> 24 & 0xff); out.write(i >> 16 & 0xff); out.write(i >> 8 & 0xff); out.write(i >> 0 & 0xff); out.write(len >> 24 & 0xff); out.write(len >> 16 & 0xff); out.write(len >> 8 & 0xff); out.write(len >> 0 & 0xff); out.write(outBuf, 0, i); out.flush(); len = 0; deflater.reset(); } } public void write(int i) throws IOException { inBuf[len++] = (byte)i; if(len == inBuf.length) compressAndSend(); } public void write(byte abyte0[], int i, int j) throws IOException { int k; for(; len + j > inBuf.length; j -= k) { k = inBuf.length - len; System.arraycopy(abyte0, i, inBuf, len, k); len += k; compressAndSend(); i += k; } System.arraycopy(abyte0, i, inBuf, len, j); len += j; } public void flush() throws IOException { compressAndSend(); out.flush(); } public void close() throws IOException { compressAndSend(); out.close(); } protected byte inBuf[]; protected byte outBuf[]; protected int len; protected Deflater deflater; }
Прошу помощи в переносе кода с Java на Delphi или в понимании этой логики "упаковки" и "шифрования" данных