网络大小端字节序,位域

大端序与小端序——字节序与位域的存储 - 大旭 - 博客园

大端序与小端序——字节序与位域的存储

谈到字节序的问题,必然牵涉到两大CPU派系——Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big-endian(大端序、大字节序、高字节序)方式存储数据,而x86系列则采用little-endian(小端序、小字节序、低字节序)方式存储数据。

  何为大端序和小端序?

  大端序:字数据的高字节存储在低地址中。

  小端序:字数据的低字节存储在低地址中。

  其实这两个概念不难理解,但是比较容易记混。由于大端序和小端序都是从存储器的低地址开始向高地址存储数据,不同的是一个字数据中先存高字节还是先存低字节。可以记住这样一个口诀:“高大低小”。“高”是指高字节,“大”是指大端序,“低”是指低字节,“小”是指小端序,“高大低小”也即先存高字节为大端序,先存低字节为小端序。

  举个常见的例子。

  位宽为32bit的CPU,要存储的字数据为0x1234abcd,起始地址为0x4000。

  大端序:

 地址  0x4000  0x4001  0x4002  0x4003 
 内容  0x12  0x34  0xab 0xcd

  小端序:

 地址  0x4000  0x4001  0x4002  0x4003 
 内容  0xcd  0xab 0x34  0x12

  以上是字节域中,比较容易理解。

  下面说一下在位域中。

  先看一个例子。

(487条消息) 位域和大小端_icesongqiang的博客-CSDN博客_大小端 位域

//小端  0001 0010 0011 0100 0101 0110 0111 1000

typedef struct{

    unsigned int first:7;       //111 1000      从低位开始

    unsigned int second:12;     //100 0101 0110 0

    unsigned int third:13;      //0001 0010 0011 0

}HighLow;

//大端  0111 1000   0101 0110  0011 0100   0001 0010

typedef struct{

    unsigned int third:13;      //0001 0010 0011 0  从低位开始。

    unsigned int second:12;     //100 0101 0110 0

    unsigned int first:7;       //111 1000

}LowHigh;

综合起来,就是两句话。

  高大低小:先存高字节为大端序,先存低字节为小端序。

  高高低低:大端序先把高bit位存储在高位地址,小端序先把低bit位存储在低位地址。

  最后附加一个常用的C程序来判断是大端序还是小端序。

网络是大端字节序

x86是小端字节序

如://192.168.5.243

大端字节序: F3 05 A8 C0               

小端 内存顺序:  c0 a8 05 f3

如int a = 128大端是 0 0 0 128      高(字节)前低(字节)后

小端   128  0 0 0      低前高后

go语言的字节序_aslackers的博客-CSDN博客

java字节序、主机字节序和网络字节序扫盲贴_aitangyong的博客-CSDN博客

java中一个int型数据占用4个字节,假如有一个16进制的int数,int value = 0x01020304;采用不同的字节序,在内存中的存储情况见下图:

显然大字节序,是比较符合人类思维习惯的。

java实现htonl

Java字节转换类实现 - fyhui - 博客园

public static int htonl(int d){
        int rslt = 0;
        byte [] bs1 = new byte[4];
        ByteUtil.putInt(bs1, d, 0);
        byte[] bs2 = ReversEndian(bs1, 4, false);
        rslt = ByteUtil.getInt(bs2, 0);
        return rslt;
    }

Java字节序(不同语言中的网络数据传输时字节序列转换)_IT小智的博客-CSDN博客

/**  
  * 将int转为低字节在前,高字节在后的byte数组  
  * @param n int  
  * @return byte[]  ntohl  小端字节序 低前高后
  */  
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[]  htonl  大端字节序  高前低后
  */  
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;  
}   
  
/**  

字节序包括:大端序和小端序,为什么要这么麻烦还要分门别类呢?举个例子,255用二进制表达就是1111 1111,再加1就是1 0000 0000,多了一个1出来,显然我们需要再用额外的一个字节来存放这个1,但是这个1要存放在第一个字节还是第二个字节呢?这时候因为人们选择的不同,就出现了大端序和小端序的差异。

而所谓大字节序(big endian),便是指其“最高有效位(most significant byte)”落在低地址上的存储方式。例如像地址a写入0x0A0B0C0D之后,在内存中的数据便是:

而对于小字节序(little endian)来说就正好相反了,它把“最低有效位(least significant byte)”放在低地址上。例如:

对于我们常用的CPU架构,如Intel,AMD的CPU使用的都是小字节序,而例如Mac OS以前所使用的Power PC使用的便是大字节序(不过现在Mac OS也使用Intel的CPU了)。

  1. 256 use big endian:

  2. int32 to bytes: [0 0 1 0]

  3. bytes to int32: 256

  4. 256 use little endian:

  5. int32 to bytes: [0 1 0 0]

  6. bytes to int32: 256

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值