字节序详解

字节序(endianness)

这篇文章来自于对How to teach endian的理解

One of the major disciplines in computer science is parsing/formatting. This is the process of converting the external format of data (file formats, network protocols, hardware registers) into the internal format (the data structures that software operates on).
解析和格式化是计算机科学中主修科目之一,它是外部数据(如文件格式、网络协议、硬件寄存器等)和内部数据(软件运行时的数据结构)相互转化的过程。

大于255的整数需要使用另外的字节进行数据表示,这些字节摆放、读取的顺序就成为字节序。

计算机硬件有两种存储数据的方式:大端字节序(big endian)和小端字节序(little endian)。

假如有一个数值为0x1234的数,高位是0x12(这里是一个字节),低位是0x34(一个字节)。
大端字节序:高位字节在前,低位字节在后。这个数字被存放为0x1234。
小端字节序:低位字节在前,高位字节在后。这个数字被存放为0x3412。

大端字节序的顺序适合人们处理数字的方式。那么为什么要使用小端字节序呢?

这是因为小端字节序的效率比大端字节序要高,在计算机电路中,先对低字节数据进行处理。

那么外部数据如何转化成内部数据(解析)的呢?
有两种方式 buffered or streaming 缓存和流。

  • 在缓存模型中,首先读取整个输入,然后再进行解析

  • 在流模型中,是一个字节读取并解析,再进行下一个字节。
    流模式最适合非常大的文件或跨TCP网络连接的流数据。

缓存模型:首先假设你将文件数据读取到了一个buffer数组中,然后
你要解析大端字节序整数x,那么
x = buffer[offset] * 256 + buffer[offset + 1]
也可以写成 x = buffer[offset] << 8 | buffer[offset + 1]
你要解析小端字节序整数y,那么
y = buffer[offset + 1] * 256 + buffer[offset]
也可以写成 x = buffer[offset + 1] << 8 | buffer[offset]

很明显大端字节序是将高位的(offset小的)放在了前面。

在Linux的头文件<netinet/ip.h>的数据结构中也可以看到。

struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN 
 u_char ip_hl:4,  /* header length */
  ip_v:4;   /* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN 
 u_char ip_v:4,   /* version */
  ip_hl:4;  /* header length */
#endif
 u_char ip_tos;   /* type of service */
 short ip_len;   /* total length */
 u_short ip_id;   /* identification */
 short ip_off;   /* fragment offset field */
 u_char ip_ttl;   /* time to live */
 u_char ip_p;   /* protocol */
 u_short ip_sum;   /* checksum */
 struct in_addr ip_src,ip_dst; /* source and dest address */
};

如果想了解更多,可以在原文中查看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值