Java 将小端转换为大端
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3842828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting Little Endian to Big Endian
提问by name_masked
All,
全部,
I have been practicing coding problems online. Currently I am working on a problem statement Problemswhere we need to convert Big Endian <-> little endian. But I am not able to jot down the steps considering the example given as:
我一直在网上练习编码问题。目前我正在处理一个问题陈述问题,我们需要转换 Big Endian <-> little endian。但考虑到以下示例,我无法记下步骤:
123456789 converts to 365779719
The logic I am considering is :
1 > Get the integer value (Since I am on Windows x86, the input is Little endian)
2 > Generate the hex representation of the same.
3 > Reverse the representation and generate the big endian integer value
我正在考虑的逻辑是:
1 > 获取整数值(因为我在 Windows x86 上,输入是小端)
2 > 生成相同的十六进制表示。
3 > 反转表示并生成大端整数值
But I am obviously missing something here.
但我显然在这里遗漏了一些东西。
Can anyone please guide me. I am coding in Java 1.5
任何人都可以请指导我。我正在用 Java 1.5 编码
采纳答案by Bryan
The thing you need to realize is that endian swaps deal with the bytes that represent the integer. So the 4 byte number 27 looks like 0x0000001B
. To convert that number, it needs to go to 0x1B000000
... With your example, the hex representation of 123456789 is 0x075BCD15
which needs to go to 0x15CD5B07
or in decimal form 365779719.
您需要意识到的是,字节序交换处理表示整数的字节。所以 4 字节数字 27 看起来像0x0000001B
. 要转换该数字,它需要转到0x1B000000
...以您的示例为例,123456789 的十六进制表示0x075BCD15
需要转到0x15CD5B07
或采用十进制形式 365779719。
The function Stacker posted is moving those bytes around by bit shifting them; more specifically, the statement i&0xff
takes the lowestbyte from i
, the << 24
then moves it up 24 bits, so from positions 1-8 to 25-32. So on through each part of the expression.
Stacker 发布的函数通过位移它们来移动这些字节;更具体地说,该语句从 中i&0xff
取出最低字节i
,<< 24
然后将其向上移动 24 位,因此从位置 1-8 到 25-32。以此类推,遍历表达式的每个部分。
For example code, take a look at thisutility.
例如代码,看看这个实用程序。
回答by stacker
Check this out
看一下这个
int little2big(int i) {
return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}
回答by Venu
I think this can also help:
我认为这也可以帮助:
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));
}
回答by Lukas Z.
the following method reverses the order of bits in a byte value:
以下方法反转字节值中的位顺序:
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);
}
回答by Wolfram Schmied
Since a great part of writing software is about reusing existing solutions, the first thing should always be a look into the documentation for your language/library.
由于编写软件的很大一部分是关于重用现有解决方案,因此首先应该始终查看您的语言/库的文档。
reverse = Integer.reverseBytes(x);
I don't know how efficient this function is, but for toggling lots of numbers, a ByteBuffer
should offer decent performance.
我不知道这个函数的效率如何,但是对于切换大量数字,aByteBuffer
应该提供不错的性能。
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);
As eversor pointed out in the comments, ByteBuffer.putInt()
is an optional method, and may not be available on all Java implementations.
正如eversor 在评论中指出的那样,ByteBuffer.putInt()
是一种可选方法,可能不适用于所有Java 实现。
The DIY Approach
DIY方法
Stacker's answer is pretty neat, but it is possible to improve upon it.
Stacker 的回答非常简洁,但可以对其进行改进。
reversed = (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
We can get rid of the parentheses by adapting the bitmasks. E. g., (a & 0xFF)<<8
is equivalent to a<<8 & 0xFF00
. The rightmost parentheses were not necessary anyway.
我们可以通过调整位掩码来去掉括号。例如,(a & 0xFF)<<8
相当于a<<8 & 0xFF00
。无论如何,最右边的括号不是必需的。
reversed = i<<24 & 0xff000000 | i<<8 & 0xff0000 | i>>8 & 0xff00 | i>>24 & 0xff;
Since the left shift shifts in zero bits, the first mask is redundant. We can get rid of the rightmost mask by using the logical shift operator, which shifts in only zero bits.
由于左移零位,因此第一个掩码是多余的。我们可以使用逻辑移位运算符去掉最右边的掩码,它只移位零位。
reversed = i<<24 | i>>8 & 0xff00 | i<<8 & 0xff0000 | i>>>24;
Operator precedencehere, the gritty details on shift operators are in the Java Language Specification
此处的运算符优先级,有关移位运算符的详细信息在Java 语言规范中
回答by glf4k
Java primitive wrapper classes support byte reversing since 1.5 using reverseBytes
method.
Java 原始包装器类从 1.5 usingreverseBytes
方法开始支持字节反转。
Short.reverseBytes(short i)
Integer.reverseBytes(int i)
Long.reverseBytes(long i)
Just a contribution for those who are looking for this answer in 2018.
只是为那些在 2018 年寻找这个答案的人的贡献。