Search code examples
javacbinarytype-conversionunsigned-integer

Proper way of converting C's uint32 to int in java


I am building a project which consists of multiple components and these components communicate with each other in byte arrays using sockets. The problem is one component is written in C and supports Unsigned primitive types while other components are written in Java and does not support Unsigned types. I am trying to develop support for Unsigned types in Java. I am new to Java. Can anyone please tell me the proper way to decode uint32 and uint64 from a byte array.

I am using the following functions for conversion of int32 and int64

public static int int32Converter(byte b[], int start) {
    return ((b[start] << 24) & 0xff000000 |(b[start + 1] << 16) & 0xff0000
            | (b[start + 2] << 8) & 0xff00 | (b[start + 3]) & 0xff);
}
public static long int64Converter(byte buf[], int start) {
    return ((buf[start] & 0xFFL) << 56) | ((buf[start + 1] & 0xFFL) << 48)
            | ((buf[start + 2] & 0xFFL) << 40)
            | ((buf[start + 3] & 0xFFL) << 32)
            | ((buf[start + 4] & 0xFFL) << 24)
            | ((buf[start + 5] & 0xFFL) << 16)
            | ((buf[start + 6] & 0xFFL) << 8)
            | ((buf[start + 7] & 0xFFL) << 0);
}

Thank you!


Solution

  • You cannot exactly "convert" them. The closest you'll find to handling unsigned values is Guava's UnsignedInteger and its utility class UnsignedInts. There is the same for bytes, shorts and longs too.

    Note about your code, don't be bothere writing such stuff by hand, use a ByteBuffer:

    public static int bytesToInt(final byte[] array, final int start)
    {
         final ByteBuffer buf = ByteBuffer.wrap(array); // big endian by default
         buf.position(start);
         buf.put(array);
         return buf.position(start).getInt();
    }
    

    Using Guava for an unsigned int:

    public static UnsignedInteger bytesToUnsignedInt(final byte[] array, final int start)
    {
             return UnsignedInteger.fromIntBits(bytesToInt(array, start);
    }
    

    However, I suspect that UnsignedInts is really what you want. (for comparison, printing them out etc)