交换多字节的顺序

时间:2015-08-04 00:25:18

标签: java

我有以十六进制格式表示的以下多字节:

0xdc, 0xd3

我可以用little endian()格式处理字节以获得十进制值54236:

List<Integer> packet = new LinkedList<Integer>(Arrays.asList(0xdc, 0xd3 ));
int idx=0;
int rpm = (int)readBytes(packet, idx, 2);

private long readBytes(List<Integer> packet, int idx, int size){
    long val=0;
    int element;

    for(int i=0;i<size;i++, idx++){
        element = packet.get(idx);
        val |= element << (8 * i);
    }

    return val;
}

上述方法按预期生成值。但是,现在我想以相反的顺序(大端格式)获取值,但它给了我一些14471936的疯狂值:

private long bigEndianReadBytes(List<Integer> packet, int idx, int size){
    long val=0;
    int element;

    for(int i=size;i>0;i--, idx++){
        element = packet.get(idx);
        val |= element << (8 * i);
    }

    return val;
}

这种方法有什么问题?

2 个答案:

答案 0 :(得分:2)

使用@TimBiegeleisen答案(+1),你有好的&#34;手册&#34;用于将字节转换为值的代码。

您是否考虑过使用ByteBuffer?它为您完成所有这些并与Big Endian和Little Endian合作。

public static void main(String[] args) throws Exception {
    ByteBuffer bb = ByteBuffer.allocate(2);
    bb.put(new byte[] {(byte)0xdc, (byte)0xd3});
    System.out.println(bb.order(ByteOrder.BIG_ENDIAN).getShort(0) & 0xFFFF);
    System.out.println(bb.order(ByteOrder.LITTLE_ENDIAN).getShort(0) & 0xFFFF);      
}

AND结果针对0xFFFF,因此short结果会提升为int,否则结果为负数,因为java使用签名数据类型。

结果:

56531
54236

答案 1 :(得分:1)

for方法中的bigEndianReadBytes()循环应该从移位size - 1字节开始,然后通过移位零字节(在最后一次迭代中)结束。目前,您在第一次迭代中移位size个字节,在最后一次迭代中移位一个字节。请尝试使用此代码:

for (int i=size-1; i >= 0; i--, idx++) {
    element = packet.get(idx);
    val |= element << (8 * i);
}