将zlib相关的python代码转换为java

问题描述 投票:0回答:1

我正在尝试将下面的python代码转换为java

 def _convert_base10encoded_to_decompressed_array(base10encodedstring) -> None:
        bytes_array = base10encodedstring.to_bytes(5000, 'big').lstrip(b'\x00')
        self.decompressed_array = zlib.decompress(bytes_array, 16+zlib.MAX_WBITS)

java代码

public void convertBase10EncodedToDecompressedArray(String base10encodedstring) throws Exception {
        // Step 1: Convert base10encodedString to a BigInteger
        BigInteger bigIntValue = new BigInteger(this.base10encodedstring);

        // Step 2: Convert BigInteger to a byte array in big-endian order
        byte[] bigIntBytes = bigIntValue.toByteArray();
        byte[] bytesArray = new byte[5000]; // Create a 5000-byte array (zero-initialized)

        // Copy the BigInteger's byte array to the end of the 5000-byte array to mimic Python's behavior
        int copyStart = 5000 - bigIntBytes.length;
        System.arraycopy(bigIntBytes, 0, bytesArray, copyStart, bigIntBytes.length);

        // Step 3: Remove leading zeros to mimic Python's lstrip(b'\x00')
        int nonZeroIndex = 0;
        while (nonZeroIndex < bytesArray.length && bytesArray[nonZeroIndex] == 0) {
            nonZeroIndex++;
        }
        byte[] trimmedBytesArray = new byte[bytesArray.length - nonZeroIndex];
        System.arraycopy(bytesArray, nonZeroIndex, trimmedBytesArray, 0, trimmedBytesArray.length);

        // Step 4: Decompress the byte array using Inflater with a header flag
        Inflater inflater = new Inflater(true); // `true` for handling zlib/gzip headers
        inflater.setInput(trimmedBytesArray);

        // Prepare output buffer for decompressed data
        byte[] output = new byte[10000]; // Adjust size as needed for decompression
        int decompressedDataLength;

        try {
            decompressedDataLength = inflater.inflate(output);
            inflater.end();
        } catch (DataFormatException e) {
            throw new Exception("Decompression failed: " + e.getMessage(), e);
        }

        // Store the decompressed data in decompressedArray
        decompressedArray = new byte[decompressedDataLength];
        System.arraycopy(output, 0, decompressedArray, 0, decompressedDataLength);
    }

java代码似乎没有像python那样进行转换并出错:

Decompression failed: invalid block type
java.lang.Exception: Decompression failed: invalid block type

这里是可用于测试的示例数据 1190424397020583291815803663391370267278476321334009149829251571002697691348854775328255423760079288536305434058868771 44858046550370019093958674847428579819304849334337536

这在 python 中运行良好,但在 Java 中失败,使用逻辑生成它

sample_data = b"This is a sample data for testing zlib decompression."

# Compress the data using gzip
buf = io.BytesIO()
with gzip.GzipFile(fileobj=buf, mode='wb') as f:
    f.write(sample_data)

compressed_data = buf.getvalue()

# Convert the compressed data to a base-10 integer
compressed_int = int.from_bytes(compressed_data, 'big')
python java encoding compression zlib
1个回答
0
投票

您可以使用 GZIPInputStream 并消除对 Inflater 的需要。这很好用:

private byte[] decompressedArray;

    public void convertBase10EncodedToDecompressedArray(String base10encodedstring) throws Exception {
        // Step 1: Convert base10encodedString to a BigInteger
        BigInteger bigIntValue = new BigInteger(base10encodedstring);

        // Step 2: Convert BigInteger to a byte array in big-endian order
        byte[] bigIntBytes = bigIntValue.toByteArray();
        byte[] bytesArray = new byte[5000]; // Create a 5000-byte array (zero-initialized)

        // Copy the BigInteger's byte array to the end of the 5000-byte array
        int copyStart = 5000 - bigIntBytes.length;
        System.arraycopy(bigIntBytes, 0, bytesArray, copyStart, bigIntBytes.length);

        // Step 3: Remove leading zeros
        int nonZeroIndex = 0;
        while (nonZeroIndex < bytesArray.length && bytesArray[nonZeroIndex] == 0) {
            nonZeroIndex++;
        }
        byte[] trimmedBytesArray = Arrays.copyOfRange(bytesArray, nonZeroIndex, bytesArray.length);

        // Step 4: Use GZIPInputStream for decompression
        try (ByteArrayInputStream bis = new ByteArrayInputStream(trimmedBytesArray);
             GZIPInputStream gzis = new GZIPInputStream(bis);
             ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            
            byte[] buffer = new byte[1024];
            int len;
            while ((len = gzis.read(buffer)) > 0) {
                bos.write(buffer, 0, len);
            }
            
            // Store the decompressed data
            decompressedArray = bos.toByteArray();
            
            // Heres output for testing
            System.out.println("Decompressed content: " + new String(decompressedArray));
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.