0

My question is about C# and Java.

I want to decompress an byte array like the method Decompress of C# from this link: https://github.com/AresChat/cb0t/blob/master/cb0t/Misc/Zip.cs

I translated the method in Java:

public static byte[] Decompress(byte[] data)
{
    try {
        Byte[] r = null;

        try (InputStream ms = new ByteArrayInputStream(data);
        InflaterInputStream s = new InflaterInputStream(ms)
        ) {
            List<Byte> list = new ArrayList<Byte>();
            int count = 0;
            byte[] b = new byte[8192];

            while ((count = s.read(b, 0, 8192)) > 0) {
                for (byte by : Arrays.copyOfRange(b,0,count+1)) {
                    list.add(by);
                }
            }

            r = list.toArray(r);
            list.clear();
            list = null;
        }
        byte[] bytes = new byte[r.length];
        int j=0;
        // Unboxing Byte values. (Byte[] to byte[])
        for(Byte b: r)
            bytes[j++] = b.byteValue();
        return bytes;
    }
    catch (Exception e){
        System.out.println(e.toString());
    }

    return new byte[] {};
}

In C#

public static void Main() 
        {
           string str = "F5fPxdTq8eJeuqSVejGmq7aTh6BJZ8J0jgt92MDDjxTIWf+mWa8Ld+01L2bVIV6FXhCO";
      byte[] val2 = Convert.FromBase64String(str);
      val2 = d67(val2, 28435);
      val2 = Zip.Decompress(val2);
      Console.WriteLine("Converted byte value: {0}", BitConverter.ToString(val2));
        }
private static byte[] d67(byte[] data, int b)
        {
            byte[] buffer = new byte[data.Length];
            Array.Copy(data, buffer, data.Length);

            for (int i = 0; i < data.Length; i++)
            {
                buffer[i] = (byte)(data[i] ^ b >> 8 & 255);
                b = (b + data[i]) * 23219 + 36126 & 65535;
            }
            return buffer;
        }

I get the output:

00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-43-48-41-54-43-48-41-4E-4E-45-4C-00-36-26-D2-37-31-D4-00-00-00-00-4D-41-59-4F-52-45-53-20-44-45-20-33-30-2C-34-30-2C-35-30-00-00

And in Java

public static void main(String[] args)
    {
        String encodedString = "arlnk://F5fPxdTq8eJeuqSVejGmq7aTh6BJZ8J0jgt92MDDjxTIWf+mWa8Ld+01L2bVIV6FXhCO";
        encodedString = encodedString.substring(8);
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decodedByteArray = decoder.decode(encodedString);
        decodedByteArray = d67(decodedByteArray, 28435);
        decodedByteArray = Zip.Decompress(decodedByteArray);
        System.out.print(hexlify(decodedByteArray));
    }

    private static byte[] d67(byte[] data, int b) {
        byte[] buffer = new byte[data.length];
        System.arraycopy(data, 0, buffer, 0, data.length);

        for (int i = 0; i < data.length; i++) {
            int unsignedData = unsignedToBytes(data[i]);

            buffer[i] = (byte) (unsignedData ^ b >> 8 & 255);

            b = (b + unsignedData) * 23219 + 36126 & 65535;
        }
        return buffer;
    }

    public static int unsignedToBytes(byte b) {
        return b & 0xFF;
    }

    public static String hexlify(byte[] data) {
        StringBuilder b = new StringBuilder();
        for (int i = 0; i < data.length; i++) {
            b.append(String.format("%02X", data[i]));
            if (i < data.length - 1) {
                b.append("-");
            }
        }
        return b.toString();
    }

I get the Exception

java.lang.NullPointerException: Attempt to get length of null array

but no output like as from C#.

What did I translate wrong? Nor can I understand why I get that exception: (...

2

1 Answer 1

1

Your Decompress method is a shambles and doesn't work at all. All it is attempting to do is to return the complete output of the inflater stream. Java has a built in method to do this, which can replace the entire thing. When you do that, you get the exact same output. Here is the full program, ready to compile and run:

import java.util.Base64;
import java.util.zip.InflaterInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

class Example {
    public static void main(String[] args) throws Exception {
        String encodedString = "arlnk://F5fPxdTq8eJeuqSVejGmq7aTh6BJZ8J0jgt92MDDjxTIWf+mWa8Ld+01L2bVIV6FXhCO";
        encodedString = encodedString.substring(8);
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decodedByteArray = decoder.decode(encodedString);
        decodedByteArray = d67(decodedByteArray, 28435);
        decodedByteArray = decompress(decodedByteArray);
        System.out.print(hexlify(decodedByteArray));
    }

    private static byte[] d67(byte[] data, int b) {
        byte[] buffer = new byte[data.length];
        System.arraycopy(data, 0, buffer, 0, data.length);

        for (int i = 0; i < data.length; i++) {
            int unsignedData = unsignedToBytes(data[i]);
            buffer[i] = (byte) (unsignedData ^ b >> 8 & 255);
            b = (b + unsignedData) * 23219 + 36126 & 65535;
        }
        return buffer;
    }

    public static int unsignedToBytes(byte b) {
        return b & 0xFF;
    }

    public static String hexlify(byte[] data) {
        StringBuilder b = new StringBuilder();
        for (int i = 0; i < data.length; i++) {
            b.append(String.format("%02X", data[i]));
            if (i < data.length - 1) {
                b.append("-");
            }
        }
        return b.toString();
    }

    public static byte[] decompress(byte[] data) throws IOException {
        try (InputStream ms = new ByteArrayInputStream(data);
        InflaterInputStream s = new InflaterInputStream(ms)) {
            return s.readAllBytes();
        }
    }
}

I didn't really change anything except the decompress method, which now contains almost no code.

Sign up to request clarification or add additional context in comments.

7 Comments

Hello rzwitserloot, thank you very much for your help. Is a Java version higher than 7 required to invoke the readAllBytes() method? I only have Java 7 available. The compiler throws me the error: "Unknown method 'readAllBytes' of 'java.util.zip.InflaterInputStream'. I want to try invoking the method having Java 7. Maybe I could...
Yes. Java7 is no longer supported and probably a security leak; upgrade it.
I use AIDE and because of that I can't upgrade Java. But if I take a look at the InflaterInputStream class I can't find the method readAllBytes()...
I don't know what AIDE is, but Java7 is not supported - if there's a security issue with that JRE or JDK nobody will update it. You must move off of it; if AIDE enforces it, then it is time to stop using that, too. You can google around for how to do what readAllBytes() does. It's a bit involved, and involves loops. There's also guava (a library), which still runs on java7 and has the method: ByteStreams.toByteArray(input) which you can use: guava.dev/releases/23.0/api/docs/com/google/common/io/…
Hello rzwitserloot, I think that I can not import external libraries for Java Console Projects. Is there no way to translate the C# code that I showed without using libraries? I would thank you it a lot...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.