读书人

关于字节序的议论

发布时间: 2012-12-25 16:18:28 作者: rapoo

关于字节序的讨论

字节序,顾名思义就是字节存放的顺序


字节序分为两种:

BIG-ENDIAN----大字节序

LITTLE-ENDIAN----小字节序


BIG-ENDIAN、LITTLE-ENDIAN与多字节类型的数据有关的比如int,short,long型,而对单字节数据byte却没有影响。

BIG-ENDIAN就是最低地址存放最高有效字节。

LITTLE-ENDIAN是最低地址存放最低有效字节。即常说的低位在先,高位在后。?


Java中int类型占4个字节,一定要是“多字节类型的数据”才有字节序问题,汉字编码也有这个问题。请看下面4字节的例子:


  比如 int a = 0x05060708?


  在BIG-ENDIAN的情况下存放为:?

  低地址------->高地址?

  字节号: 第0字节,第1字节,第2字节,第3字节?

  数 ?据: 05 ? ?, 06 ? , 07 ? , 08?


  在LITTLE-ENDIAN的情况下存放为:?

  低地址------->高地址?

  字节号: 第0字节,第1字节,第2字节,第3字节?

  数 ?据: 08 ? ?, 07 ? , 06 ? , 05?



JAVA字节序:

指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。?


主机字节序:

Intel的x86系列CPU是Little-Endian,而PowerPC 、SPARC和Motorola处理器是BIG-ENDIAN。

ARM同时支持 big和little,实际应用中通常使用little endian。是BIG-ENDIAN还是LITTLE-ENDIAN的跟CPU有关的,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN。


网络字节序:

4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作大端字节序(BIG-ENDIAN)。 TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序。


不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。

? ? 处理器 ? ? 操作系统 ? 字节排序

? ? Alpha ? ? 全部 ? ? ? ?Little endian

? ? HP-PA ? ? NT ? ? ? ? ?Little endian

? ? HP-PA ? ? UNIX ? ? ? ?Big endian

? ? Intelx86 ?全部 ? ? ? ?Little endian



所以在用C/C++写通信程序时,在发送数据前务必用htonl和htons去把整型和短整型的数据进行从主机字节序到网络字节序的转换,而接收数据后对于整型和短整型数据则必须调用ntohl和ntohs实现从网络字节序到主机字节序的转换。如果通信的一方是JAVA程序、一方是C/C++程序时,则需要在C/C++一侧使用以上几个方法进行字节序的转换,而JAVA一侧,则不需要做任何处理,因为JAVA字节序与网络字节序都是BIG-ENDIAN,只要C/C++一侧能正确进行转换即可(发送前从主机序到网络序,接收时反变换)。如果通信的双方都是JAVA,则根本不用考虑字节序的问题了。?

?

java中转换字节序

?

方案一:通过ByteBuffer实现

?

?

方案二:自己写代码实现

?

?关于字节序的议论关于字节序的议论
    package?com.xxx; ????/** ??*?通信格式转换 ??*? ??*?Java和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换?高、低字节之间的转换 ??*?windows的字节序为低字节开头?linux,unix的字节序为高字节开头?java则无论平台变化,都是高字节开头 ??*/??public?class?FormatTransfer?{ ?? ????/** ??????*?将int转为低字节在前,高字节在后的byte数组 ??????*? ??????*?@param?n ??????*????????????int ??????*?@return?byte[] ??????*/??????public?static?byte[]?toLH(int?n)?{ ?? ????????byte[]?b?=?new?byte[4]; ?? ????????b[0]?=?(byte)?(n?&?0xff); ?? ????????b[1]?=?(byte)?(n?>>?8?&?0xff); ?? ????????b[2]?=?(byte)?(n?>>?16?&?0xff); ?? ????????b[3]?=?(byte)?(n?>>?24?&?0xff); ?? ????????return?b; ?? ????} ????????/** ??????*?将int转为高字节在前,低字节在后的byte数组 ??????*? ??????*?@param?n ??????*????????????int ??????*?@return?byte[] ??????*/??????public?static?byte[]?toHH(int?n)?{ ?? ????????byte[]?b?=?new?byte[4]; ?? ????????b[3]?=?(byte)?(n?&?0xff); ?? ????????b[2]?=?(byte)?(n?>>?8?&?0xff); ?? ????????b[1]?=?(byte)?(n?>>?16?&?0xff); ?? ????????b[0]?=?(byte)?(n?>>?24?&?0xff); ?? ????????return?b; ?? ????} ????????/** ??????*?将short转为低字节在前,高字节在后的byte数组 ??????*? ??????*?@param?n ??????*????????????short ??????*?@return?byte[] ??????*/??????public?static?byte[]?toLH(short?n)?{ ?? ????????byte[]?b?=?new?byte[2]; ?? ????????b[0]?=?(byte)?(n?&?0xff); ?? ????????b[1]?=?(byte)?(n?>>?8?&?0xff); ?? ????????return?b; ?? ????} ????????/** ??????*?将short转为高字节在前,低字节在后的byte数组 ??????*? ??????*?@param?n ??????*????????????short ??????*?@return?byte[] ??????*/??????public?static?byte[]?toHH(short?n)?{ ?? ????????byte[]?b?=?new?byte[2]; ?? ????????b[1]?=?(byte)?(n?&?0xff); ?? ????????b[0]?=?(byte)?(n?>>?8?&?0xff); ?? ????????return?b; ?? ????} ????????/** ??????*?将将int转为高字节在前,低字节在后的byte数组?public?static?byte[]?toHH(int?number)?{?int ??????*?temp?=?number;?byte[]?b?=?new?byte[4];?for?(int?i?=?b.length?-?1;?i?>?-1; ??????*?i--)?{?b?=?new?Integer(temp?&?0xff).byteValue();?temp?=?temp?>>?8;?} ??????*?return?b;?}?public?static?byte[]?IntToByteArray(int?i)?{?byte[]?abyte0?= ??????*?new?byte[4];?abyte0[3]?=?(byte)?(0xff?&?i);?abyte0[2]?=?(byte)?((0xff00?& ??????*?i)?>>?8);?abyte0[1]?=?(byte)?((0xff0000?&?i)?>>?16);?abyte0[0]?=?(byte) ??????*?((0xff000000?&?i)?>>?24);?return?abyte0;?} ??????*/??????/** ??????*?将float转为低字节在前,高字节在后的byte数组 ??????*/??????public?static?byte[]?toLH(float?f)?{ ?? ????????return?toLH(Float.floatToRawIntBits(f)); ?? ????} ????????/** ??????*?将float转为高字节在前,低字节在后的byte数组 ??????*/??????public?static?byte[]?toHH(float?f)?{ ?? ????????return?toHH(Float.floatToRawIntBits(f)); ?? ????} ????????/** ??????*?将String转为byte数组 ??????*/??????public?static?byte[]?stringToBytes(String?s,?int?length)?{ ?? ????????while?(s.getBytes().length?<?length)?{ ?? ????????????s?+=?"?"; ?? ????????} ??????????return?s.getBytes(); ?? ????} ????????/** ??????*?将字节数组转换为String ??????*? ??????*?@param?b ??????*????????????byte[] ??????*?@return?String ??????*/??????public?static?String?bytesToString(byte[]?b)?{ ?? ????????StringBuffer?result?=?new?StringBuffer(""); ?? ????????int?length?=?b.length; ?? ????????for?(int?i?=?0;?i?<?length;?i++)?{ ?? ????????????result.append((char)?(b[i]?&?0xff)); ?? ????????} ??????????return?result.toString(); ?? ????} ????????/** ??????*?将字符串转换为byte数组 ??????*? ??????*?@param?s ??????*????????????String ??????*?@return?byte[] ??????*/??????public?static?byte[]?stringToBytes(String?s)?{ ?? ????????return?s.getBytes(); ?? ????} ????????/** ??????*?将高字节数组转换为int ??????*? ??????*?@param?b ??????*????????????byte[] ??????*?@return?int ??????*/??????public?static?int?hBytesToInt(byte[]?b)?{ ?? ????????int?s?=?0; ?? ????????for?(int?i?=?0;?i?<?3;?i++)?{ ?? ????????????if?(b[i]?>=?0)?{ ?? ????????????????s?=?s?+?b[i]; ??????????????}?else?{ ?? ????????????????s?=?s?+?256?+?b[i]; ?? ????????????} ??????????????s?=?s?*?256; ?? ????????} ??????????if?(b[3]?>=?0)?{ ?? ????????????s?=?s?+?b[3]; ?? ????????}?else?{ ?? ????????????s?=?s?+?256?+?b[3]; ?? ????????} ??????????return?s; ?? ????} ????????/** ??????*?将低字节数组转换为int ??????*? ??????*?@param?b ??????*????????????byte[] ??????*?@return?int ??????*/??????public?static?int?lBytesToInt(byte[]?b)?{ ?? ????????int?s?=?0; ?? ????????for?(int?i?=?0;?i?<?3;?i++)?{ ?? ????????????if?(b[3?-?i]?>=?0)?{ ?? ????????????????s?=?s?+?b[3?-?i]; ?? ????????????}?else?{ ?? ????????????????s?=?s?+?256?+?b[3?-?i]; ?? ????????????} ??????????????s?=?s?*?256; ?? ????????} ??????????if?(b[0]?>=?0)?{ ?? ????????????s?=?s?+?b[0]; ?? ????????}?else?{ ?? ????????????s?=?s?+?256?+?b[0]; ?? ????????} ??????????return?s; ?? ????} ????????/** ??????*?高字节数组到short的转换 ??????*? ??????*?@param?b ??????*????????????byte[] ??????*?@return?short ??????*/??????public?static?short?hBytesToShort(byte[]?b)?{ ?? ????????int?s?=?0; ?? ????????if?(b[0]?>=?0)?{ ?? ????????????s?=?s?+?b[0]; ?? ????????}?else?{ ?? ????????????s?=?s?+?256?+?b[0]; ?? ????????} ??????????s?=?s?*?256; ?? ????????if?(b[1]?>=?0)?{ ?? ????????????s?=?s?+?b[1]; ?? ????????}?else?{ ?? ????????????s?=?s?+?256?+?b[1]; ?? ????????} ??????????short?result?=?(short)?s; ?? ????????return?result; ?? ????} ????????/** ??????*?低字节数组到short的转换 ??????*? ??????*?@param?b ??????*????????????byte[] ??????*?@return?short ??????*/??????public?static?short?lBytesToShort(byte[]?b)?{ ?? ????????int?s?=?0; ?? ????????if?(b[1]?>=?0)?{ ?? ????????????s?=?s?+?b[1]; ?? ????????}?else?{ ?? ????????????s?=?s?+?256?+?b[1]; ?? ????????} ??????????s?=?s?*?256; ?? ????????if?(b[0]?>=?0)?{ ?? ????????????s?=?s?+?b[0]; ?? ????????}?else?{ ?? ????????????s?=?s?+?256?+?b[0]; ?? ????????} ??????????short?result?=?(short)?s; ?? ????????return?result; ?? ????} ????????/** ??????*?高字节数组转换为float ??????*? ??????*?@param?b ??????*????????????byte[] ??????*?@return?float ??????*/??????public?static?float?hBytesToFloat(byte[]?b)?{ ?? ????????int?i?=?0; ?? ????????Float?F?=?new?Float(0.0); ?? ????????i?=?((((b[0]?&?0xff)?<<?8?|?(b[1]?&?0xff))?<<?8)?|?(b[2]?&?0xff))?<<?8?|?(b[3]?&?0xff); ?? ????????return?F.intBitsToFloat(i); ?? ????} ????????/** ??????*?低字节数组转换为float ??????*? ??????*?@param?b ??????*????????????byte[] ??????*?@return?float ??????*/??????public?static?float?lBytesToFloat(byte[]?b)?{ ?? ????????int?i?=?0; ?? ????????Float?F?=?new?Float(0.0); ?? ????????i?=?((((b[3]?&?0xff)?<<?8?|?(b[2]?&?0xff))?<<?8)?|?(b[1]?&?0xff))?<<?8?|?(b[0]?&?0xff); ?? ????????return?F.intBitsToFloat(i); ?? ????} ????????/** ??????*?将byte数组中的元素倒序排列 ??????*/??????public?static?byte[]?bytesReverseOrder(byte[]?b)?{ ?? ????????int?length?=?b.length; ?? ????????byte[]?result?=?new?byte[length]; ?? ????????for?(int?i?=?0;?i?<?length;?i++)?{ ?? ????????????result[length?-?i?-?1]?=?b[i]; ?? ????????} ??????????return?result; ?? ????} ????????/** ??????*?打印byte数组 ??????*/??????public?static?void?printBytes(byte[]?bb)?{ ?? ????????int?length?=?bb.length; ?? ????????for?(int?i?=?0;?i?<?length;?i++)?{ ?? ????????????System.out.print(bb?+?"?"); ?? ????????} ??????????System.out.println(""); ?? ????} ????????public?static?void?logBytes(byte[]?bb)?{ ?? ????????int?length?=?bb.length; ?? ????????String?out?=?""; ?? ????????for?(int?i?=?0;?i?<?length;?i++)?{ ?? ????????????out?=?out?+?bb?+?"?"; ?? ????????} ??????} ????????/** ??????*?将int类型的值转换为字节序颠倒过来对应的int值 ??????*? ??????*?@param?i ??????*????????????int ??????*?@return?int ??????*/??????public?static?int?reverseInt(int?i)?{ ?? ????????int?result?=?FormatTransfer.hBytesToInt(FormatTransfer.toLH(i)); ?? ????????return?result; ?? ????} ????????/** ??????*?将short类型的值转换为字节序颠倒过来对应的short值 ??????*? ??????*?@param?s ??????*????????????short ??????*?@return?short ??????*/??????public?static?short?reverseShort(short?s)?{ ?? ????????short?result?=?FormatTransfer.hBytesToShort(FormatTransfer.toLH(s)); ?? ????????return?result; ?? ????} ????????/** ??????*?将float类型的值转换为字节序颠倒过来对应的float值 ??????*? ??????*?@param?f ??????*????????????float ??????*?@return?float ??????*/??????public?static?float?reverseFloat(float?f)?{ ?? ????????float?result?=?FormatTransfer.hBytesToFloat(FormatTransfer.toLH(f)); ?? ????????return?result; ?? ????} ??}??

ByteBuffer类中的order(ByteOrder bo) 方法可以设置 ByteBuffer 的字节序。?

?

其中的ByteOrder是枚举:?

ByteOrder BIG_ENDIAN ?代表大字节序的 ByteOrder 。

ByteOrder LITTLE_ENDIAN ?代表小字节序的 ByteOrder 。

ByteOrder nativeOrder() ?返回当前硬件平台的字节序。

?

?

?

读书人网 >编程

热点推荐