大小端字节序/网络字节序

字节序

计算机上的数据在内存中是以1 字节(Byte)为单位存储的,1Byte = 8bits, 这是因为电子计算机ROM的最小信息单位是bit, 而CPU的数据总线一般为8根,即一次可读取1Byte.

对于长度为1Byte的char型,不存在字节序的问题。而对于长度大于1Byte的数据类型,就存在字节序的问题。

大、小端字节序

大端字节序: 高位字节数据存放在内的低地址处,低位数据存放在内的高地址处;
小端字节序: 高位字节数据存放在内的高地址处,低位数据存放在内的低地址处;

以长度为4字节的int型为例,0x12345678的十进制为305419896, 如果是大端字节序的机器,它在内存中的存放为:
低地址 -------------> 高地址
0x12 | 0x34 | 0x56 | 0x78
而在小端字节序的机器上,则为
从低地址到高地址: 78 56 34 12

这两个概念很容易搞混,有如下巧记法:

一般网络字节序为大端字节序,因为UDP/TCP/IP协议规定:把接收到的第一个字节当作高位字节看待,网络数据解析时先收到的数据存放于低地址,否则内存的访问将是不连续的。 所以,大端字节序 = 网络字节序 = 高位放低地址。

大小端机器检测

我们常用的X86结构是小端模式,而几种检测的方法:

  1. 直接取低地址字节
BOOL IsBigEndian()
{
	int a = 0x1234;
	char b =  *(char *)&a;  //通过将int强制类型转换成char单字节,通过判断起始存储位置。即等于 取b等于a的低地址部分
	if( b == 0x12)
	{
		return TRUE;
	}
	return FALSE;
} 
  1. 使用union
BOOL IsBigEndian()
{
	union NUM
	{
		int a;
		char b;
	}num;
	num.a = 0x1234;
	if( num.b == 0x12 )
	{
		return TRUE;
	}
	return FALSE;
} 

大小端类型转换

2字节和4字节

	template<typename T>
    constexpr
    typename std::enable_if<std::is_same<T, uint32_t>::value, uint32_t>::type
    swap (T value) noexcept
    {
       return  ((value & 0x000000FF) << 24)
             | ((value & 0x0000FF00) <<  8)
             | ((value & 0x00FF0000) >>  8)
             | ((value & 0xFF000000) >> 24);
    }

    template<typename T>
    constexpr
    typename std::enable_if<std::is_same<T, uint16_t>::value, uint16_t>::type
    swap (T value) noexcept
    {
        return  ((value & 0x00FF) <<  8)
              | ((value & 0xFF00) >>  8);
    }

8字节

# define swap_64(x) \
     (__extension__ ((((x) & 0xff00000000000000ull) >> 56)		      \
		     | (((x) & 0x00ff000000000000ull) >> 40)		      \
		     | (((x) & 0x0000ff0000000000ull) >> 24)		      \
		     | (((x) & 0x000000ff00000000ull) >> 8)		      \
		     | (((x) & 0x00000000ff000000ull) << 8)		      \
		     | (((x) & 0x0000000000ff0000ull) << 24)		      \
		     | (((x) & 0x000000000000ff00ull) << 40)		      \
		     | (((x) & 0x00000000000000ffull) << 56)))

参考:
https://blog.youkuaiyun.com/qq_27384769/article/details/80700320
https://blog.youkuaiyun.com/dange4/article/details/80277898

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值