`
flychao88
  • 浏览: 753170 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于字节序的讨论

 
阅读更多

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


字节序分为两种:

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实现

 

 

方案二:自己写代码实现

 

Java代码 复制代码 收藏代码
  1. package com.xxx;   
  2.   
  3. /**  
  4.  * 通信格式转换  
  5.  *   
  6.  * Java和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换 高、低字节之间的转换  
  7.  * windows的字节序为低字节开头 linux,unix的字节序为高字节开头 java则无论平台变化,都是高字节开头  
  8.  */  
  9. public class FormatTransfer {   
  10.     /**  
  11.      * 将int转为低字节在前,高字节在后的byte数组  
  12.      *   
  13.      * @param n  
  14.      *            int  
  15.      * @return byte[]  
  16.      */  
  17.     public static byte[] toLH(int n) {   
  18.         byte[] b = new byte[4];   
  19.         b[0] = (byte) (n & 0xff);   
  20.         b[1] = (byte) (n >> 8 & 0xff);   
  21.         b[2] = (byte) (n >> 16 & 0xff);   
  22.         b[3] = (byte) (n >> 24 & 0xff);   
  23.         return b;   
  24.     }   
  25.   
  26.     /**  
  27.      * 将int转为高字节在前,低字节在后的byte数组  
  28.      *   
  29.      * @param n  
  30.      *            int  
  31.      * @return byte[]  
  32.      */  
  33.     public static byte[] toHH(int n) {   
  34.         byte[] b = new byte[4];   
  35.         b[3] = (byte) (n & 0xff);   
  36.         b[2] = (byte) (n >> 8 & 0xff);   
  37.         b[1] = (byte) (n >> 16 & 0xff);   
  38.         b[0] = (byte) (n >> 24 & 0xff);   
  39.         return b;   
  40.     }   
  41.   
  42.     /**  
  43.      * 将short转为低字节在前,高字节在后的byte数组  
  44.      *   
  45.      * @param n  
  46.      *            short  
  47.      * @return byte[]  
  48.      */  
  49.     public static byte[] toLH(short n) {   
  50.         byte[] b = new byte[2];   
  51.         b[0] = (byte) (n & 0xff);   
  52.         b[1] = (byte) (n >> 8 & 0xff);   
  53.         return b;   
  54.     }   
  55.   
  56.     /**  
  57.      * 将short转为高字节在前,低字节在后的byte数组  
  58.      *   
  59.      * @param n  
  60.      *            short  
  61.      * @return byte[]  
  62.      */  
  63.     public static byte[] toHH(short n) {   
  64.         byte[] b = new byte[2];   
  65.         b[1] = (byte) (n & 0xff);   
  66.         b[0] = (byte) (n >> 8 & 0xff);   
  67.         return b;   
  68.     }   
  69.   
  70.     /**  
  71.      * 将将int转为高字节在前,低字节在后的byte数组 public static byte[] toHH(int number) { int  
  72.      * temp = number; byte[] b = new byte[4]; for (int i = b.length - 1; i > -1;  
  73.      * i--) { b = new Integer(temp & 0xff).byteValue(); temp = temp >> 8; }  
  74.      * return b; } public static byte[] IntToByteArray(int i) { byte[] abyte0 =  
  75.      * new byte[4]; abyte0[3] = (byte) (0xff & i); abyte0[2] = (byte) ((0xff00 &  
  76.      * i) >> 8); abyte0[1] = (byte) ((0xff0000 & i) >> 16); abyte0[0] = (byte)  
  77.      * ((0xff000000 & i) >> 24); return abyte0; }  
  78.      */  
  79.     /**  
  80.      * 将float转为低字节在前,高字节在后的byte数组  
  81.      */  
  82.     public static byte[] toLH(float f) {   
  83.         return toLH(Float.floatToRawIntBits(f));   
  84.     }   
  85.   
  86.     /**  
  87.      * 将float转为高字节在前,低字节在后的byte数组  
  88.      */  
  89.     public static byte[] toHH(float f) {   
  90.         return toHH(Float.floatToRawIntBits(f));   
  91.     }   
  92.   
  93.     /**  
  94.      * 将String转为byte数组  
  95.      */  
  96.     public static byte[] stringToBytes(String s, int length) {   
  97.         while (s.getBytes().length < length) {   
  98.             s += " ";   
  99.         }   
  100.         return s.getBytes();   
  101.     }   
  102.   
  103.     /**  
  104.      * 将字节数组转换为String  
  105.      *   
  106.      * @param b  
  107.      *            byte[]  
  108.      * @return String  
  109.      */  
  110.     public static String bytesToString(byte[] b) {   
  111.         StringBuffer result = new StringBuffer("");   
  112.         int length = b.length;   
  113.         for (int i = 0; i < length; i++) {   
  114.             result.append((char) (b[i] & 0xff));   
  115.         }   
  116.         return result.toString();   
  117.     }   
  118.   
  119.     /**  
  120.      * 将字符串转换为byte数组  
  121.      *   
  122.      * @param s  
  123.      *            String  
  124.      * @return byte[]  
  125.      */  
  126.     public static byte[] stringToBytes(String s) {   
  127.         return s.getBytes();   
  128.     }   
  129.   
  130.     /**  
  131.      * 将高字节数组转换为int  
  132.      *   
  133.      * @param b  
  134.      *            byte[]  
  135.      * @return int  
  136.      */  
  137.     public static int hBytesToInt(byte[] b) {   
  138.         int s = 0;   
  139.         for (int i = 0; i < 3; i++) {   
  140.             if (b[i] >= 0) {   
  141.                 s = s + b[i];   
  142.             } else {   
  143.                 s = s + 256 + b[i];   
  144.             }   
  145.             s = s * 256;   
  146.         }   
  147.         if (b[3] >= 0) {   
  148.             s = s + b[3];   
  149.         } else {   
  150.             s = s + 256 + b[3];   
  151.         }   
  152.         return s;   
  153.     }   
  154.   
  155.     /**  
  156.      * 将低字节数组转换为int  
  157.      *   
  158.      * @param b  
  159.      *            byte[]  
  160.      * @return int  
  161.      */  
  162.     public static int lBytesToInt(byte[] b) {   
  163.         int s = 0;   
  164.         for (int i = 0; i < 3; i++) {   
  165.             if (b[3 - i] >= 0) {   
  166.                 s = s + b[3 - i];   
  167.             } else {   
  168.                 s = s + 256 + b[3 - i];   
  169.             }   
  170.             s = s * 256;   
  171.         }   
  172.         if (b[0] >= 0) {   
  173.             s = s + b[0];   
  174.         } else {   
  175.             s = s + 256 + b[0];   
  176.         }   
  177.         return s;   
  178.     }   
  179.   
  180.     /**  
  181.      * 高字节数组到short的转换  
  182.      *   
  183.      * @param b  
  184.      *            byte[]  
  185.      * @return short  
  186.      */  
  187.     public static short hBytesToShort(byte[] b) {   
  188.         int s = 0;   
  189.         if (b[0] >= 0) {   
  190.             s = s + b[0];   
  191.         } else {   
  192.             s = s + 256 + b[0];   
  193.         }   
  194.         s = s * 256;   
  195.         if (b[1] >= 0) {   
  196.             s = s + b[1];   
  197.         } else {   
  198.             s = s + 256 + b[1];   
  199.         }   
  200.         short result = (short) s;   
  201.         return result;   
  202.     }   
  203.   
  204.     /**  
  205.      * 低字节数组到short的转换  
  206.      *   
  207.      * @param b  
  208.      *            byte[]  
  209.      * @return short  
  210.      */  
  211.     public static short lBytesToShort(byte[] b) {   
  212.         int s = 0;   
  213.         if (b[1] >= 0) {   
  214.             s = s + b[1];   
  215.         } else {   
  216.             s = s + 256 + b[1];   
  217.         }   
  218.         s = s * 256;   
  219.         if (b[0] >= 0) {   
  220.             s = s + b[0];   
  221.         } else {   
  222.             s = s + 256 + b[0];   
  223.         }   
  224.         short result = (short) s;   
  225.         return result;   
  226.     }   
  227.   
  228.     /**  
  229.      * 高字节数组转换为float  
  230.      *   
  231.      * @param b  
  232.      *            byte[]  
  233.      * @return float  
  234.      */  
  235.     public static float hBytesToFloat(byte[] b) {   
  236.         int i = 0;   
  237.         Float F = new Float(0.0);   
  238.         i = ((((b[0] & 0xff) << 8 | (b[1] & 0xff)) << 8) | (b[2] & 0xff)) << 8 | (b[3] & 0xff);   
  239.         return F.intBitsToFloat(i);   
  240.     }   
  241.   
  242.     /**  
  243.      * 低字节数组转换为float  
  244.      *   
  245.      * @param b  
  246.      *            byte[]  
  247.      * @return float  
  248.      */  
  249.     public static float lBytesToFloat(byte[] b) {   
  250.         int i = 0;   
  251.         Float F = new Float(0.0);   
  252.         i = ((((b[3] & 0xff) << 8 | (b[2] & 0xff)) << 8) | (b[1] & 0xff)) << 8 | (b[0] & 0xff);   
  253.         return F.intBitsToFloat(i);   
  254.     }   
  255.   
  256.     /**  
  257.      * 将byte数组中的元素倒序排列  
  258.      */  
  259.     public static byte[] bytesReverseOrder(byte[] b) {   
  260.         int length = b.length;   
  261.         byte[] result = new byte[length];   
  262.         for (int i = 0; i < length; i++) {   
  263.             result[length - i - 1] = b[i];   
  264.         }   
  265.         return result;   
  266.     }   
  267.   
  268.     /**  
  269.      * 打印byte数组  
  270.      */  
  271.     public static void printBytes(byte[] bb) {   
  272.         int length = bb.length;   
  273.         for (int i = 0; i < length; i++) {   
  274.             System.out.print(bb + " ");   
  275.         }   
  276.         System.out.println("");   
  277.     }   
  278.   
  279.     public static void logBytes(byte[] bb) {   
  280.         int length = bb.length;   
  281.         String out = "";   
  282.         for (int i = 0; i < length; i++) {   
  283.             out = out + bb + " ";   
  284.         }   
  285.     }   
  286.   
  287.     /**  
  288.      * 将int类型的值转换为字节序颠倒过来对应的int值  
  289.      *   
  290.      * @param i  
  291.      *            int  
  292.      * @return int  
  293.      */  
  294.     public static int reverseInt(int i) {   
  295.         int result = FormatTransfer.hBytesToInt(FormatTransfer.toLH(i));   
  296.         return result;   
  297.     }   
  298.   
  299.     /**  
  300.      * 将short类型的值转换为字节序颠倒过来对应的short值  
  301.      *   
  302.      * @param s  
  303.      *            short  
  304.      * @return short  
  305.      */  
  306.     public static short reverseShort(short s) {   
  307.         short result = FormatTransfer.hBytesToShort(FormatTransfer.toLH(s));   
  308.         return result;   
  309.     }   
  310.   
  311.     /**  
  312.      * 将float类型的值转换为字节序颠倒过来对应的float值  
  313.      *   
  314.      * @param f  
  315.      *            float  
  316.      * @return float  
  317.      */  
  318.     public static float reverseFloat(float f) {   
  319.         float result = FormatTransfer.hBytesToFloat(FormatTransfer.toLH(f));   
  320.         return result;   
  321.     }   
  322. }  

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

 

其中的ByteOrder是枚举: 

ByteOrder BIG_ENDIAN  代表大字节序的 ByteOrder 。

ByteOrder LITTLE_ENDIAN  代表小字节序的 ByteOrder 。

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

 

 

 

分享到:
评论

相关推荐

    stm32f103的4字节转float和float转4字节代码

    STM32F103通常是小端字节序,但如果你需要在不同字节序的系统间交换数据,可能需要进行字节序转换,例如使用`ntohl`(网络字节序到主机字节序)和`htonl`(主机字节序到网络字节序)函数。 以上就是关于STM32F103上...

    JAVA作业三字节数组转化.docx

    字节序分为大端字节序(Big-Endian)和小端字节序(Little-Endian)。大端字节序是指最高位(最显著的位)的字节位于最低地址,而小端字节序则相反,最低位的字节位于最低地址。 在`intToBytes`方法中,我们看到的...

    034 gbk_utf_ansi_asc字符集分析字节序.7z

    在这个"034 gbk_utf_ansi_asc字符集分析字节序"的压缩包中,很可能是提供了关于这些编码格式的详细分析,包括它们的字节表示、转换过程和可能遇到的问题。分析这些内容有助于深入理解字符编码的原理,从而在实际开发...

    浮点数与4字节数值相互转换工具

    因此,在进行跨平台数据交换时,需要考虑字节序问题,确保正确解读4字节数值。 总的来说,浮点数与4字节数值的转换涉及到对二进制表示的理解,包括符号、指数和尾数的处理,以及可能的字节顺序问题。通过掌握这些...

    关于.txt总结

    根据描述,我们主要讨论两种字节序:小端字节序(Little Endian)和大端字节序(Big Endian),这两种字节序在不同的处理器架构中有不同的应用。 #### 小端字节序(Little Endian) 小端字节序的特点是将低字节存储...

    Little_Big_endian.rar_big endian_little

    这里我们主要讨论两种字节顺序:大端字节序(Big-endian)和小端字节序(Little-endian)。这两个术语源自Gulliver's Travels中的两个部落名称,用来形象地描述数据在内存中的排列方式。 标题“Little_Big_endian....

    swap_io.rar_swap

    "swap_io.rar_swap"这个标题暗示了我们正在讨论与字节交换相关的操作,可能是一个用于处理字节序转换的库或者工具。描述中的“大小字节转换”进一步明确了这一点,它指的是在大端字节序(Big-Endian)和小端字节序...

    hyts_Foo.rar_swap

    描述中的信息进一步确认了这一点,它提到告诉"sys endian.h"我们有MD变种的交换宏,这表明我们在讨论的是关于计算机体系结构中字节序处理的问题。 在计算机科学中,字节序是内存中多字节数值的字节排列顺序。有两种...

    易语言自定义数据类型与字节集转换源码

    这种转换通常涉及对数据类型的字段进行逐个读取或写入,以及可能的字节序处理(如大端序和小端序)。 在易语言中,实现这样的转换可以使用各种内置函数和命令。例如,可以使用“结构到字节集”命令将自定义数据类型...

    baycom.rar_little

    描述中提到的"ARM supports little-endian and big-endian for linux Device Driver"进一步确认了我们在讨论ARM处理器在Linux设备驱动程序中的字节序支持。 首先,让我们来理解一下字节序。字节序是指多字节数据...

    e^2prom单字节.zip_多字节

    2. 数据存储格式:解释如何组织和编码多字节数据,例如采用大端或小端字节序来存储多字节数值。 3. 单字节操作:介绍如何向EEPROM写入一个字节,并读取该字节的方法,通常涉及I/O操作和特定的编程API。 4. 多字节...

    android byte字节数组转换十六进制字符串

    3. 在转换过程中,可能会遇到字节顺序问题,特别是在处理网络字节序和本地字节序时。在Android中,通常不需要担心这个问题,因为byte数组通常不涉及字节序。 总结,Android中将字节数组转换为十六进制字符串的方法...

    字节转换请求工具共11页.pdf.zip

    这个工具可能是程序员、网络开发者或者数据处理人员使用的,帮助他们处理二进制数据,进行不同编码间的转换,例如ASCII到UTF-8,或者其他特定的字节序转换,如大端序到小端序。 标签“字节转换请求工具共11页.pdf”...

    linux网络编程[收集].pdf

    在网络通信中,为了确保不同字节序的计算机间能够正确交换数据,TCP/IP协议定义了一种标准的字节序,即网络字节序,它采用大端字节序。例如,16位的端口号1000(0x3e8)在网络传输时,应当按照0x03(低地址)和0xe8...

    4字节16进制数转换为float浮点数的原理及Qt算法实现示例

    同时,注意在进行这种低级操作时,确保数据类型匹配和大小端问题,因为不同的系统可能使用不同的字节序。在必要的时候,还需要进行字节序转换(如大端转小端,小端转大端)以确保数据正确解读。 总的来说,4字节...

    speex_header.rar_little_speex

    标题中的"speex_header.rar_little_speex"暗示了我们正在处理与Speex音频编码相关的文件,特别是关于处理小端字节序的头文件。Speex是一种免费的、开源的、可扩展的音频编解码器,专为语音通信优化,尤其是在网络...

    About-Endian.zip_Word for Word

    例如,它可能会讨论TCP/IP协议栈如何处理字节序,或者在Java编程语言中如何使用`java.nio.ByteOrder`类来处理字节序。 总之,Endian是计算机科学中一个基础但至关重要的概念,理解它对于进行系统设计、网络编程和...

    套节字函数1

    1. `ntohs(u_short)` 和 `htons(u_short)`:这两个函数分别用于将16位的网络字节序转换为主机字节序,以及将16位的主机字节序转换为网络字节序。`ntohs` 是 "Network to Host Short" 的缩写,`htons` 是 "Host to ...

    第4次Linux综合报告-终1

    网络字节序,也称为网络标准字节序,是TCP/IP协议规定的一种统一的字节序,即大端字节序。当不同平台的计算机进行网络通信时,为了保证数据的一致性,必须将本地的数据转换成网络字节序进行传输,接收方再将其转换回...

Global site tag (gtag.js) - Google Analytics