将Little Endian转换为Big Endian

时间:2010-10-01 20:26:44

标签: java portability

所有

我一直在网上练习编码问题。目前我正在处理问题陈述Problems,我们需要转换Big Endian< - >小端。但考虑到给出的例子,我无法记下步骤:

123456789 converts to 365779719

我正在考虑的逻辑是:
1>获取整数值(因为我在Windows x86上,输入是Little endian)
2>生成相同的十六进制表示 3>反转表示并生成大端整数值

但我显然在这里遗漏了一些东西。

任何人都可以指导我。我在Java 1.5中编码

7 个答案:

答案 0 :(得分:27)

由于编写软件的很大一部分是重用现有的解决方案,所以首先应该总是查看语言/库的文档。

reverse = Integer.reverseBytes(x);

我不知道这个函数的效率如何,但是为了切换大量数字,ByteBuffer应该提供不错的性能。

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

...

int[] myArray = aFountOfIntegers();
ByteBuffer buffer = ByteBuffer.allocate(myArray.length*Integer.BYTES);

buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int x:myArray) buffer.putInt(x);

buffer.order(ByteOrder.BIG_ENDIAN);
buffer.rewind();
int i=0;
for (int x:myArray) myArray[i++] = buffer.getInt(x);

正如eversor在评论中指出的那样,ByteBuffer.putInt()是一种可选方法,可能并非在所有Java实现中都可用。

DIY方法

Stacker的答案非常简洁,但有可能对其进行改进。

   reversed = (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;

我们可以通过调整位掩码来摆脱括号。例如,(a & 0xFF)<<8相当于a<<8 & 0xFF00。无论如何,最右边的括号都没有必要。

   reversed = i<<24 & 0xff000000 | i<<8 & 0xff0000 | i>>8 & 0xff00 | i>>24 & 0xff;

由于左移位为零位,因此第一个掩码是冗余的。我们可以通过使用逻辑移位运算符来消除最右边的掩码,该运算符仅移位零位。

   reversed = i<<24 | i>>8 & 0xff00 | i<<8 & 0xff0000 | i>>>24;

Operator precedence此处,有关移位运算符的详细信息位于Java Language Specification

答案 1 :(得分:25)

检查出来

int little2big(int i) {
    return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}

答案 2 :(得分:21)

你需要意识到的是,endian交换处理代表整数的字节。所以4字节数字27看起来像0x0000001B。要转换该数字,需要转到0x1B000000 ...在您的示例中,123456789的十六进制表示形式为0x075BCD15,需要转到0x15CD5B07或十进制形式365779719。 / p>

Stacker发布的函数是通过位移来移动这些字节;更具体地说,语句i&0xffi获取最低字节,<< 24然后将其向上移动24位,因此从位置1-8到25- 32。所以通过表达式的每个部分。

例如代码,请查看this实用程序。

答案 3 :(得分:6)

Java基本包装器类从1.5开始就使用reverseBytes方法支持字节反转。

Short.reverseBytes(short i)
Integer.reverseBytes(int i)
Long.reverseBytes(long i)

对于那些在2018年寻找此答案的人来说只是一个贡献。

答案 4 :(得分:0)

我认为这也有帮助:

int littleToBig(int i)
{
    int b0,b1,b2,b3;

    b0 = (i&0x000000ff)>>0;
    b1 = (i&0x0000ff00)>>8;
    b2 = (i&0x00ff0000)>>16;
    b3 = (i&0xff000000)>>24;

    return ((b0<<24)|(b1<<16)|(b2<<8)|(b3<<0));
}

答案 5 :(得分:0)

以下方法反转字节值中的位顺序:

public static byte reverseBitOrder(byte b) {
    int converted = 0x00;
    converted ^= (b & 0b1000_0000) >> 7;
    converted ^= (b & 0b0100_0000) >> 5;
    converted ^= (b & 0b0010_0000) >> 3;
    converted ^= (b & 0b0001_0000) >> 1;
    converted ^= (b & 0b0000_1000) << 1;
    converted ^= (b & 0b0000_0100) << 3;
    converted ^= (b & 0b0000_0010) << 5;
    converted ^= (b & 0b0000_0001) << 7;

    return (byte) (converted & 0xFF);
}

答案 6 :(得分:0)

只需使用java中Integer Wrapper类下的静态函数(reverseBytes(int i))

Integer i=Integer.reverseBytes(123456789);
System.out.println(i);

输出:

365779719