图解字节序大小端、比特序大小端

2023-05-16

先建立几个常识:

  • 一般机器的字节序大小端和比特序大小端是一致的。
  • 人类阅读时,从左向右进行阅读,所以先看到数字的高位,最后才能看到数字的低位。所以,人类的阅读顺序,天然是大端顺序。大端顺序是更方便人类阅读和表述的顺序。比如0xfedc,我们是认为f是最高位,c是最低位;比如0b01101111,我们是将0看成是最高位,1看成是最低位。

字节序大小端

大端:存储值的高位在低地址,存储值的低位在高地址。比如0x01是该数字的最高字节,但却是存储在0x100,最低的地址;0x67是该数字的最小值的字节,存储在0x103这个最高地址。

小端:存储值的高位在高地址,存储值的低位在低地址。

在这里插入图片描述

字节序转化函数

  • uint16_t htons(uint16_t):用于将按本机字节序存储的16位整数转化为网络字节序;
  • uint16_t ntohs(uint16_t):用于将按网络字节序存储的16位整数转化为本机字节序;
  • uint32_t htonl(uint32_t):用于将按本机字节序存储的32位整数转化为网络字节序;
  • uint32_t ntohl(uint32_t):用于将按网络字节序存储的32位整数转化为本机字节序;
    以上四个函数名中,h,n,s,l分别代表主机,网络,短整数,长整数。前两个函数在网络编程中常用于转换端口号,后面个则是用于转换ipv4地址。

通过字节转换函数我们就可以在字节大小端之间根据需要进行转换。

比特序大小端

字节序是一个对象中的多个字节之间的顺序问题,比特序就是一个字节中的8个比特位(bit)之间的顺序问题。一般情况下系统的比特序和字节序是保持一致的。一个字节由8个bit组成,这8个bit也存在如何排序的情况,跟字节序类似的有最高有效比特位、最低有效比特位。比特序(LSB)1 0 0 1 0 0 1 0(MSB)在大端系统中最高有效比特位为1、最低有效比特位为0,字节的值为0x92。在小端系统中最高、最低有效比特位则相反为0、1,字节的值为0x49。跟字节序类似,要想保持一个字节值不变那么就要使系统能正确的识别最高、最低有效比特位。

  • 比特序小端:将最高有效比特位放在了bit0,将最低有效比特位放在了bit7;

  • 比特序大端:将最高有效比特位放在了bit7,将最低有效比特位放在了bit0;

image-20210727214938759

image-20210727215002106

通过上图我们知道 字节地址顺序和比特顺序是不变的,大小端的不同在于机器怎么对这些地址空间进行填充。

我们可以将字节地址顺序和比特顺序看作是硬件性质。


字节序转换后我在想是不是比特序也一同进行了转换?

为什么会有这个疑问呢,因为前文可知系统的比特序和字节序是一致的,现在字节序已经从小端变成了大端那么比特序应该也要一起转换。而且如果比特序不变化那么当这些字节到了目标大端序系统中后每一个字节的值都会发生变化,因为同样的比特序列在小端和大端系统中识别的字节值会不一样。
首先从htonl、ntohl的源码来看确实只进行了字节序的转换并没有进行比特序的转换,再有就是以前socket编程的时候只调用了ntohl、htonl等函数并没有调用(而且系统也没有提供)比特序转换函数,但是最后的结果都是正确的,并没有发现上面提到的字节值发生变化的问题。
那么这个”神奇”的事情是怎么解决的呢,好像系统本身就给我们”悄悄”的解决了我担心的问题。

比特(bit)的发送和接收顺序

比特的发送、接收顺序是指一个字节中的bit在网络电缆中是如何发送、接收的。在以太网(Ethernet)中,是从最低有效比特位到最高有效比特位的发送顺序,也就是最低有效比特位首先发送,参考资料:frame。
 在以太网中这个规定有点奇怪,因为字节序我们是按照大端序来发送,但是比特序却是按照小端序的方式来发送,下图是直接从网上找来的一张图,主机序本身是大端序

https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210727223540800.png

比特的发送、接收顺序对CPU、软件都是不可见的,因为我们的网卡会给我们处理这种转换,在发送的时候按照小端序发送比特位,在接收的时候会把接收到的比特序转换成主机的比特序,下面是一个小端机器发送一个int整型给一个大端机器的示意图:

https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210727223718906.png

  • htonl、ntohl函数肯定是不会同步转换一个字节中的比特序的,因为如果比特序也发生了转换的话那么这个字节的值也就发生了变化,记住htonl、ntohl只是字节序转换函数。
  • 比特序按照小端的方式发送,首先发送的是最低有效比特位,最后发送的是最高有效比特位,接收端的网卡在接收到比特序列后按照主机的比特序把接收到的”小端序”比特流转换成主机对应的比特序列。
  • 可以假设存在ntohb、htonb(b代表bit)这样的两个函数,网卡进行了比特序的转换,不过是这两个函数是网卡自动调用的,我们平时不用关注。
    按照规则,发送、接收的时候进行比特序的转换,那么就能保证在不同的机器之间进行通信不会发生我担心的字节值发生变化的问题。

大小端转换综合应用

现在假设两种应用场景:

  • 大端机器接收来自小端机器的数据,在此过程中我们不做任何处理,看看应该怎么使用这个数据。
  • 小端机器接收来自大端机器的数据,在此过程中我们不做任何处理,看看应该怎么使用这个数据。

大端机器接收来自小端机器的数据

假设下图是来自小端机器的数据,现在原封不动的传入到大端机器中

https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210727224920226.png

大端机器其实会将上图数据解释成

https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210727230010886.png

如果我们传输的这个4个字节的数据包含一定含义,那么在大端机器上,我们要怎么还原出这个含义呢?

假设这4个字节在原来小段机器上的含义如下图

image-20210727231918245

字节0x0000是一个位域

字节0x0001也是一个位域

字节0x0002和字节0x0003代表一个short整型数据的两个字节。

可以看出,要想在大端机器上还原小端机器上数据的含义还是很麻烦的。

要还原字节0x0002和字节0x0003代表的short整型数据,我们既要倒置字节的位置,还要倒置比特的位置,用起来很麻烦。

字节0x0000和字节0x0001都是使用一个字节中的位,因此还原起来还是比较简单的。因为比特序大小端的不同,原来我们在小端机器上的低位,在大端机器上就变成了高位。

如果位域中的元素每一位都是一个比特,那还比较好理解,但是如果位域中的元素超过一个比特,那应该怎么还原呢?

对于位域有一个约定:在C语言的结构体中如果包含了位域,如果位域A定义在位域B之前,那么位域A总是出现在低序的比特位。

我们还是要旋转位才能还原数据的含义。


总结

可以看出,字节大小端和比特大小端还是很多需要注意的地方,不过只有我们掌握了怎么测试机器的字节序大小端和比特序大小端,了解怎么转换字节序和比特序,我们就可以将数据还原成数据本身的含义。

(261条消息) 图解字节序大小端、比特序大小端_小熊coder的博客-CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图解字节序大小端、比特序大小端 的相关文章

随机推荐

  • 所有线段的交点-初级篇

    所有线段的交点 初级篇 标签 xff08 空格分隔 xff09 xff1a 计算机视觉 图形学 所有线段的交点 初级篇 参考 xff1a 计算几何 算法与应用 邓俊辉 译 清华大学出版社 本文以一个小例子介绍如何计算所有线段交点 xff0c
  • 服务器docker使用

    这篇文章是我给自己的一个记录 xff0c 有些名词可能写的不专业 xff0c 请见谅 docker里面有两个概念 xff0c 一个是镜像 xff0c 一个是容器 镜像可以看做是类 xff0c 容器就是类的实例 在学院的服务器上 xff0c
  • MPC模型预测控制

    这篇主要讲一下模型预测控制 xff0c 如果对PID控制了解的同学 xff0c 那效果更好 如果不了解PID控制 xff0c 还是熟悉下比较好 模型预测控制 xff0c 顾名思义 xff0c 基于模型 xff0c 预测未来 xff0c 进行
  • MPC自学资料总结

    1 书籍 xff1a 无人驾驶车辆模型预测控制 2 视频 xff1a https ww2 mathworks cn videos understanding model predictive control part 1 why use m
  • [授权发表]基于 VNCServer + noVNC 构建 Docker 桌面系统

    by Falcon of TinyLab org 2015 05 02 最初发表 xff1a 泰晓科技 聚焦嵌入式 Linux xff0c 追本溯源 xff0c 见微知著 xff01 原文链接 xff1a 基于 VNCServer 43 n
  • 【c语言】字符串输出方式 | API仿真

    创作不易 xff0c 本篇文章如果帮助到了你 xff0c 还请点赞 关注支持一下 gt x16966 lt 主页专栏有更多知识 xff0c 如有疑问欢迎大家指正讨论 xff0c 共同进步 xff01 给大家跳段街舞感谢支持 xff01 c语
  • 【c语言】结构体详解 | 结构体数组/指针

    创作不易 xff0c 本篇文章如果帮助到了你 xff0c 还请点赞 关注支持一下 gt x16966 lt 主页专栏有更多知识 xff0c 如有疑问欢迎大家指正讨论 xff0c 共同进步 xff01 x1f525 c语言系列专栏 xff1a
  • stm32F4系列学习笔记1: keil使用

    一 在keil的find功能中有几个find options xff0c 查了一下 xff0c 这几个find options的意思是 1 Match case 区分大小写 2 Regular expression 正则表达式 3 Matc
  • STM32F4系列学习笔记2:IO相关

    一 寄存器说明 xff1a STM32F4 GPIO最多有9组 xff0c 从GPIOA GPIOI xff0c 每组IO有16个Pin xff0c STM32F407有7组 xff0c 所以一共有7 16 61 112个引脚 xff0c
  • 树莓派Ubuntu20.04创建虚拟内存文件并设置开机自动启用

    目录 一 检查有没有虚拟内存 二 创建虚拟内存文件并设置权限 三 设置并激活虚拟内存文件 四 设置开机自动启用虚拟内存 五 重启后检测虚拟内存是否正常启用 一 检查有没有虚拟内存 树莓派Ubuntu20 04默认没有虚拟内存 xff0c 可
  • 如何配置 QEMU 虚拟机网络

    关于 QEMU 的网络策略 QEMU 提供 4 种网络通信方法 xff0c 它们分别是 xff1a User mode stack xff1a 用户协议栈方式 xff0c 这种方式的大概原理是在 QEMU 进程中实现一个协议栈 xff0c
  • Pygame库的使用-1 初识Pygame

    本文参考链接如下 xff1a 1 https zhuanlan zhihu com p 1366649502 https www bilibili com video BV1bE411p7Ue from 61 search amp seid
  • 电机知识入门 有刷 | 无刷

    一 总述 直流电动机按结构及工作原理可划分为无刷直流电机 BLDC电机 和有刷直流电机 BDC电机 二 差异 BDC是Brushed DC Motor的缩写 xff0c BLDC是Brushless DC Motor的缩写BLDC电机 直流
  • PCB设计1 模块间的隔离

    想要给板子的各个部分进行电气隔离 xff0c 比如电源转压之后的各个电压12V 5V 3 3V 和用电的设备之间进行隔离 xff0c 本来的想法是用2pin的跳线帽 xff0c 但是在参考了一些资料之后 xff0c 对2pin跳线帽有了一个
  • Ubuntu18.04 更改apt-get 的时候会访问的软件源列表

    像这样 xff0c 每次在sudo apt get update的时候会有很多访问的软件源列表 xff0c 但是有的时候自己安装了一些软件比如说nordvpn xff0c 这样的时候就会自动的为我们增加apt get的源 xff0c 但是往
  • 安装油猴插件解决chatgpt报错问题

    转载自Github Daily公众号 Something went wrong If this issue persists please contact usthrough our help center at help openai c
  • Ubuntu18.04安装Elevation_Map并测试

    参考 elevation mapping at master ANYbotics elevation mapping GitHub 安装elevation mapping与traversability estimation elevatio
  • Vue:button按钮的点击

    调用 xff1a lt button class 61 34 toast 34 v on click 61 34 addEvent 34 gt toast gt lt button gt script lt script gt export
  • Vslam方案+源码,轻松搞定视觉slam

    原创 xff1a 涛涛CV 涛涛CV 今天 关注涛涛CV xff0c 设为星标 xff0c 更新不错过 VSLAM方案 目前基于视觉的SLAM技术有多种组合形式 xff08 见下表 xff09 方案 特点 TOF 成本高 xff0c 分辨率
  • 图解字节序大小端、比特序大小端

    先建立几个常识 xff1a 一般机器的字节序大小端和比特序大小端是一致的 人类阅读时 xff0c 从左向右进行阅读 xff0c 所以先看到数字的高位 xff0c 最后才能看到数字的低位 所以 xff0c 人类的阅读顺序 xff0c 天然是大