Bitconverter for Java
Asked Answered
N

4

10

Following the advice provided in the question https://stackoverflow.com/questions/1738244/what-is-the-java-equivalent-of-net-bitconverter I have begun implementing my own bitconverter for Java but am not getting equivalent results.

Could someone please guide me on what I might be doing incorrectly?

public static byte[] GetBytes(Integer value) {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    DataOutputStream stream = new DataOutputStream(byteStream);
    try {
        stream.writeInt(value);
    } catch (IOException e) {
        return new byte[4];
    }
    return byteStream.toByteArray();
}

byte[] result = BitConverter.GetBytes(1234); //JAVA: [0, 0, 4, -46]
byte[] result = BitConverter.GetBytes(1234); //C#: [210, 4, 0, 0]
Nunez answered 3/5, 2011 at 6:10 Comment(0)
C
11

That is just endianness (-46 and 210 is because of Java's signed bytes, but that is just a UI thing). Either reverse the array contents, or use shift operations to write the int.

Note: the endianness that .NET emits depends on the platform. I would suggest using KNOWN ENDIANNESS in both cases; most likely by using shift operations from both. Or perhaps a better idea: just use a pre-canned, platform independent serialization format (for example: protocol buffers, which has good support on both Java and .NET/C#).

For example; if I was writing an int value to a byte[] buffer (starting at offset), I might use:

buffer[offset++] = (byte)value;
buffer[offset++] = (byte)(value>>8);
buffer[offset++] = (byte)(value>>16);
buffer[offset++] = (byte)(value>>24);

this is guaranteed little-endian, and similar code should work on any framework.

Chandlery answered 3/5, 2011 at 6:16 Comment(1)
what is offset value?Volplane
B
5

The C# BitConverter will use the endianness of the underlying achitecture. In most environments, it will be little-endian (as it is in your case). Java's DataOutputStream however will always write in big-endian ("the portable way"). You'll need to check the endianness of the machine and write accordingly if you want to match the behavior.

Also, bytes in java are signed so the output is just a cosmetic difference. The bit representation is the same so you don't need to worry about that.

To check the endianness of your machine, use the java.nio.ByteOrder.nativeOrder() method. Then use the java.nio.ByteBuffer instead where you may specify the byte order() and write the data.

You could then implement your method like this:

public static byte[] GetBytes(int value)
{
    ByteBuffer buffer = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder());
    buffer.putInt(value);
    return buffer.array();
}
Bemean answered 3/5, 2011 at 6:27 Comment(0)
H
4

if any body need..C# to JAVA BitConverter.ToInt32

  public static int toInt32_2(byte[] bytes, int index)
        {
            int a = (int)((int)(0xff & bytes[index]) << 32 | (int)(0xff & bytes[index + 1]) << 40 | (int)(0xff & bytes[index + 2]) << 48 | (int)(0xff & bytes[index + 3]) << 56);
            // int a = (int)((int)(0xff & bytes[index]) << 56 | (int)(0xff & bytes[index + 1]) << 48 | (int)(0xff & bytes[index + 2]) << 40 | (int)(0xff & bytes[index + 3]) << 32);
            //Array.Resize;
            return a;
        }

Also Int16

    public static short toInt16(byte[] bytes, int index) //throws Exception
    {
        return (short)((bytes[index + 1] & 0xFF) | ((bytes[index] & 0xFF) << 0));
        //return (short)(
        //        (0xff & bytes[index]) << 8 |
        //                (0xff & bytes[index + 1]) << 0
        //);
    }

BitConverter.getBytes

public static byte[] GetBytesU16(long value)
{

    ByteBuffer buffer = ByteBuffer.allocate(8).order(ByteOrder.nativeOrder());
    buffer.putLong(value);
    return buffer.array();
}
Heterotopia answered 28/6, 2016 at 13:56 Comment(0)
R
1

Building on Jeff's answer, you can use a single ByteBuffer to convert both to and from int and byte[]. Here is code you can drop into a class to convert to/from Little Endian:

ByteBuffer _intShifter = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE)
                                   .order(ByteOrder.LITTLE_ENDIAN);

public byte[] intToByte(int value) {
    _intShifter.clear();
    _intShifter.putInt(value);      
    return _intShifter.array();
}

public int byteToInt(byte[] data)
{
    _intShifter.clear();
    _intShifter.put(data, 0, Integer.SIZE / Byte.SIZE);
    _intShifter.flip();
    return _intShifter.getInt();
}
Rathskeller answered 21/11, 2014 at 23:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.