开发者

How can I convert a 4-byte array to an integer?

I want to perform a conversion without resorting to some implementation-开发者_Python百科dependent trick. Any tips?


You need to know the endianness of your bytes.

Assuming (like @WhiteFang34) that bytes is a byte[] of length 4, then...

Big-endian:

int x = java.nio.ByteBuffer.wrap(bytes).getInt();

Little-endian:

int x = java.nio.ByteBuffer.wrap(bytes).order(java.nio.ByteOrder.LITTLE_ENDIAN).getInt();


Assuming bytes is a byte[4] of an integer in big-endian order, typically used in networking:

int value = ((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16)
        | ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);

The & 0xFF are necessary because byte is signed in Java and you need to retain the signed bit here. You can reverse the process with this:

bytes[0] = (byte) ((value >> 24) & 0xFF);
bytes[1] = (byte) ((value >> 16) & 0xFF);
bytes[2] = (byte) ((value >> 8) & 0xFF);
bytes[3] = (byte) (value & 0xFF);


Not sure if this is correct java syntax, but how about:

int value = 0;
for (i = 0; i <= 3; i++)
    value = (value << 8) + (bytes[i] & 0xFF);


You need to specify the byte order of the array, but assuming that the bytes[0] is the most significant byte then:

int res = ((bytes[0] & 0xff) << 24) | ((bytes[1] & 0xff) << 16) |
          ((bytes[2] & 0xff) << 8)  | (bytes[3] & 0xff);

This code is 100% portable, assuming that you use the reverse algorithm to create the byte array in the first place.


Byte order problems arise in languages where you can cast between a native integer type and byte array type ... and then discover that different architectures store the bytes of an integer in different orders.

You can't do that cast in Java. So for Java to Java communication, this should not be an issue.

However, if you are sending or receiving packets to some remote application that is implemented in (say) C or C++, you need to "know" what byte order is being used in the network packets. Some alternative strategies for knowing / figuring this out are:

  • Everyone uses "network order" (big-endian) for stuff on the wire as per the example code above. Non-java applications on little-endian machines need to flip the bytes.

  • The sender finds out what order the receiver expects and uses that order when assembling the data.

  • The receiver figures out what order the sender used (e.g. via a flag in the packet) and decodes accordingly.

The first approach is simplest and most widely used, though it does result in 2 unnecessary endian-ness conversions if both the sender and receiver are little-endian.

See http://en.wikipedia.org/wiki/Endianness


Assuming your byte[] come from somewhere e.g. a stream you can use

DataInputStream dis = ... // can wrap a new ByteArrayInputStream(bytes)
int num = dis.readInt(); // assume big-endian.

or

ByteChannel bc = ... // can be a SocketChannel
ByteBuffer bb = ByteBuffer.allocate(64*1024);

bc.read(bb);
bb.flip();
if (bb.remaining()<4) // not enough data

int num = bb.getInt();

When you send data, you should know if you are sending big-endian or little endian. You have to assume other things such as whether you are sending a 4-byte signed integer. A binary protocol is full of assumptions. (Which makes it more compact and faster, but more brittle than text)

If you don't want to be making as many assumptions, send text.


WE can also use following to make it more dynamic byte array size
BigEndian Format:

public static int pareAsBigEndianByteArray(byte[] bytes) {
    int factor = bytes.length - 1;
    int result = 0;
    for (int i = 0; i < bytes.length; i++) {
        if (i == 0) {
            result |= bytes[i] << (8 * factor--);
        } else {
            result |= bytes[i] << (8 * factor--);
        }
    }
    return result;
}

Little Endian Format :

public static int pareAsLittleEndianByteArray(byte[] bytes) {
    int result = 0;
    for (int i = 0; i < bytes.length; i++) {
        if (i == 0) {
            result |= bytes[i] << (8 * i);
        } else {
            result |= bytes[i] << (8 * i);
        }
    }
    return result;
}

This will helps you lot for converting bytes to int values


public static int toInt( byte[] bytes ) {
int result = 0;
for (int i=0; i<3; i++) {
  result = ( result << 8 ) - Byte.MIN_VALUE + (int) bytes[i];
}
return result;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜