`
flychao88
  • 浏览: 745265 次
  • 性别: 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()  返回当前硬件平台的字节序。

 

 

 

分享到:
评论

相关推荐

    Python+文本分析合集

    它是一种不可变序的UNICODE或字符。有一点必须仔细区分:Python 3中,所有字符串默认是UNICODE;但在Python 2中,str类限制为ASCII码,需要另外一个UNICODE类来专门处理UNICODE。 UNICODE仅仅是一种编码语言或处理...

    单片机系统设计的可靠性.doc

    单片机系统设计的可靠性 【摘要】: 对单片机实际应用中遇到的、与可靠性技术有关的问题进行了讨论,并分析了一些可行 的办法。 【关键词】:单片机;抗干扰;可靠性;稳定性 一、单片机选型 在单片机系统设计的初始...

    Reversing:逆向工程揭密

    1.4.3 虚拟机和字节码 12 1.4.4 操作系统 13 1.5 逆向过程 13 1.5.1 系统级逆向 14 1.5.2 代码级逆向 14 1.6 工具 14 1.6.1 系统监控工具 15 1.6.2 反汇编器 15 1.6.3 调试器 15 1.6.4 反编译器 16 1.7 逆向合法吗?...

    Java经典入门教程pdf完整版

    杂性,同时提供对现有应用稈序集成强有力支持,完全支持 Entcrprise java beans,有良 好的向导攴持打包和部署应用,添加了目录攴持,增强了安全机制,提高了性能 JE是对标准版进行功能扩展,提供一系列功能,用来解决进行...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...

    XML高级编程pdf

    译者序 作者简介 前言 第1章 XML简介 1.1 标记语言 1.2 XML的起源和目的 1.3 Web体系结构:过去与未来 1.3.1 传统Web体系结构 1.3.2 XML下的Web体系结构 1.4 XML基本特征 1.5 词汇表 1.5.1 科学词汇表 ...

    XML 高级编程(高清版)

    译者序 作者简介 前言 第1章 XML简介 1.1 标记语言 1.2 XML的起源和目的 1.3 Web体系结构:过去与未来 1.3.1 传统Web体系结构 1.3.2 XML下的Web体系结构 1.4 XML基本特征 1.5 词汇表 1.5.1 科学词汇表 ...

    《WINDOWS网络编程技术》

    本书专门讨论Windows网络编程技术,覆盖Windows 95/98/NT 4/2000/CE平台,内容包括NetBIOS和Windows重定向器方法、Winsock方法、客户端远程访问服务器方法,本书论述深入浅出、用大量实例详解了微软网络API函数的...

    XML高级编程

    译者序 作者简介 前言 第1章 XML简介 1 1.1 标记语言 1 1.2 XML的起源和目的 2 1.3 Web体系结构:过去与未来 4 1.3.1 传统Web体系结构 4 1.3.2 XML下的Web体系结构 5 1.4 XML基本特征 6 1.5 词汇表 8 1.5.1 科学词汇...

    building_storage_networks_chsSAN存储区域网络 .rar

    国际数据公司(IDC)预言:若按磁盘的每兆字节价格计算,在2003年之前,磁盘存储系统的价格平均每年将下降40%。事实上,不考虑其他的因素,仅考虑新的硬盘驱动器一项,就能得出上述结论,因为磁盘的记录密度每12~...

    岳维功 ortp-realease.pdf

    则由上面讨论可知,时间戳单位为 ,我们就假设 钟被划分了个时间块,如果每秒发送帧,那么,每·个帧的发送占多少个时间块 呢?当然是 。因此,我们根据定义“时间戳增量是发送第二个包相距 发送第一个包时的时间问隔”,故...

    C#微软培训资料

    14.4 继承中关于属性的一些问题.169 14.5 小 结 .172 第四部分 深入了解 C#.174 第十五章 接 口 .174 15.1 组件编程技术 .174 15.2 接 口 定 义 .177 15.3 接口的成员 .178 15.4 接口的实现 .182 ...

    C语言程序设计标准教程

    与前面讨论的各类指针变量相同,结构指针变量也必须要先赋值后才能使用。赋值是把结构变量的首地址赋予该指针变量, 不能把结构名赋予该指针变量。如果boy是被说明为stu类型的结构变量,则: pstu=&boy是正确的,而...

Global site tag (gtag.js) - Google Analytics