如何理解字节序

PyTorch模型生产部署:ONNX/Triton导出与高可用架构实战 机器学习模型部署本质是训练环境与生产环境之间的运行时契约建立过程,涉及序列化协议、推理引擎兼容性、动态批处理及资源隔离等核心问题。ONNX凭借标准化算子集和跨框架支持,成为平衡兼容性、性能与可维护性的首选导出格式;Triton Inference Server则通过原生多框架支持、动态batching和热加载能力,显著提升GPU利用率与服务SLA保障水平。在金融风控、电商推荐等高要求场景中,基于ONNX+Triton+K8s的分层架构可稳定支撑千级QPS与毫秒级P95延迟,同时满足模型热更新、可观测性与版本 阅读详情

计算机只能理解 0 和 1 组成的二进制数据, 一个 bit 的值是 0 或 1,八个这样的 bit 组成了一个字节,通过字节,计算机可以表示一些复杂的数据,比如:音频、视频等,有些数据只需要用一个字节来表示,比如英文字符,而有些数据需要多个字节来表示,比如:汉字,
对于多字节的数据,存储的时候会有字节顺序的问题,也就是字节序

字节序是什么

字节序是计算机存储多字节数据的方式,目前主流的方式有:大端字节序和小端字节序,字节序主要是针对多字节的数据类型,比如 short、int 等类型

  • 大端字节序

高位字节存储在内存的低地址上,低位字节存储在内存的高位地址上

  • 小端字节序

高位字节存储在内存的高地址上,低位字节存储在内存的低地址上

如何理解字节序

我们平常书写和阅读数字的习惯是从左到右的,所以把最左边的字节当作最高位字节,最右边的字节当作做最低位字节,从左到右,表示从高位字节到低位字节

比如:对于 0x01020304,它的大端和小端字节序在内存中的布局如下图所示

0x 01 02 03 04 总共四个字节大小,以人们习惯的阅读顺序,0x01 处于左边,属于高位字节,0x04 处于右边,属于低位字节

内存地址从 0x 00 00 00 070x 00 00 00 0A 4个字节的空间,刚好能存储得下

根据大端字节序的的规则:高位字节存储在内存低地址,所以处于高位字节的 0x01 存储在 0x 00 00 00 07 地址处,紧接着 次高位字节 0x02 存储在次低地址 0x 00 00 00 08 处,剩下的两个字节 0x030x04 分别存储于 0x 00 00 00 090x 00 00 00 0A 地址处,最终以 0x 01 02 03 04 存储

小端字节序和大端刚好相反,它指的是 高位字节存储在内存高地址处,所以处于高位字节的 0x01 存储在 0x 00 00 00 0A 地址处,次高位字节 0x02 存储在次高地址 0x 00 00 00 09 处,余下的 0x030x04 分别存储于 0x 00 00 00 080x 00 00 00 07 地址处,最终以 0x 04 03 02 01 存储

上图可以看出,对于相同的数据,在大端和小端下的内存布局是不一样的,大端字节序的存储形式更符合人们平常书写和阅读的习惯

为什么会有字节序

可能有人会感到疑惑:既然大端字节序更符合人们阅读的习惯,为什么不全部都采用大端的方式,这样也就不会有字节序的问题了 ?

确实,如果所有平台都用同一种存储顺序,就没有字节序这一说法了

在早期, CPU 只有几千个逻辑门,小端的方式能更有效的使用逻辑电路,所以很多计算机内部计算都采用小端的方式,这种方式也就保留到了现在

另外,字节序是跟 CPU 架构相关,不同的厂家设计的规范可能都不一样,比如 Intel 的 x86 是小端方式,而 IBM 的 PowerPC 则采用大端方

大端的方式更符合人们的阅读习惯,因此大部分网络传输以及文件存储都是大端的方式

总的来说,小端主要是在计算机内部使用,大端则在外部使用

计算机如何处理字节序

计算机读取数据的时候是不区分字节序的,它总是从内存低地址到高地址的顺序,按字节读取

下面的示例图展示了数据 0x0102 的 大端和小端的内存布局以及CPU读取内存的顺序

由上图可知,对于大端字节序来说,内存低地址处存储的是高位字节,也即计算机读取内存的第一个字节就是高位字节,小端字节序就正好相反,内存低地址处存储的是低位字节,读取内存的第一个字节是低位字节

计算机只有在读取数据的时候才需要区分字节序

就拿上面展示大端方式的图 ( 第一张 ) 来说,内存 0x 00 00 00 07 地址处存储的数据是 0x01 0x 00 00 00 08 地址处存储的数据是 0x02

如果是以大端的方式读取的话,地址 0x 00 00 00 07 处的数据 0x01 会放到高位字节, 0x 00 00 00 08 处的数据是 0x02 放到低位字节,最终这两个字节的数据是 0x 01 02

如果是以小端的方式读取的话,,地址 0x 00 00 00 07 处的数据 0x01 会放到低位字节, 0x 00 00 00 08 处的数据是 0x02 放到高位字节,最终这两个字节的数据是 0x 02 01

网络字节序

所有的协议都是为人类编写的,大端对人们阅读更友好,所以 IEEE 标准协会规定除非有明确说明,否则网络协议都使用大端字节序, 像 TCP/IP 就使用大端序

还记得我们在编写网络程序的时候,传入 connect 函数实参中的 端口号吗, 传入之前需调用 htons 函数将其转成网络字节序,也就是要转成大端字节序,下面是部分代码示例

struct sockaddr_in server_addr;

server_addr.sin_family = AF_INET;

server_addr.sin_addr.s_addr = inet_addr(“192.168.1.10”);

server_addr.sin_port = htons( 5000 );

connect( clientfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) )

上面红色的 htons 函数的作用是将 端口号 由主机字节序转成网络字节序,网络字节序大多时候都是固定为大端字节序的,但不同的机器,主机字节序却不一样,如果本身就已经是大端了,调用 htons 函数,返回值和实参是一样的,如果本身是小端,结果会转成大端的形式

怎么判断大小端

上面提到了主机字节序,那如何知道当前机器是大端还是小端呢 ?

因为操作系统必须适配所有类型的 CPU ,所以对于操作系统来说,大端和小端都是支持的

为了让程序易于判断当前平台是大端还是小端,Linux 下 glibc 库提供了下面几个宏定义

BIG_ENDIAN          # 大端序
LITTLE_ENDIAN       # 小端序
BYTE_ORDER          # 字节序

下面是测试代码 test.c 文件

#include <stdio.h>
int main(int argc, char *argv[])
{
    if(BYTE_ORDER == BIG_ENDIAN)
    {
        printf("big endian...\n");
    }
    else
    {
        printf("little endian...\n");
    }
}

执行 gcc -g -o test test.c 命令进行编译,运行测试程序,结果如下:

[root@localhost test]# ./test
little endian...

由此,可以知道当前平台是小端字节序

除了用上面的方法之外,我们可以根据大端和小端的特点,自己写代码获取,修改 test.c文件,内容如下

#include <stdio.h>
int main(int argc, char *argv[])
{
    union
    {
        unsigned short i;
        char ch[2];
    }un;
    
    un.i = 0x0102;
    if(0x01 == un.ch[0])
    {
         printf("big endian...\n");
    }
    else
    {
         printf("little endian...\n");
    }
}

编译并运行,结果如下:

[root@localhost test]# ./test
little endian...

可以看出,不管是通过系统库提供的宏来判断还是自行封装接口来判断都是可行的

最后,如果想知道 LITTLE_ENDIAN、 BIG_ENDIAN 、BYTE_ORDER 宏定义的详细情况,可以查看 glibc 源码,它们在 glibc-2.17\string\endian.h 以及 glibc-2.17\sysdeps\x86\bits\endian.h 文件中

注意:不同版本的 glibc 源码,具体的位置可能有差异,我使用的是 glibc-2.17

大端小端的转换

熟悉了大端和小端定义,它们之间的转换就简单了,对于两字节来说,每个字节值不变,互换字节位置,如果是更多字节的话,最低位字节和最高位字节交换,次低位字节与次高位字节交换,直到所有字节都完成了一遍交换为止

比如:下面是小端转大端的伪代码

#小端转大端  假如:ch 和 i  是小端序

char ch[2];

int i = 0;

# x 是大端字节序
x = ch[1] << 8 | ch[0] 

# y 是大端字节序
y =   ( (i & 0xff000000) >> 24 ) |  ( (i & 0x00ff0000) >> 8 ) | ( (i & 0x0000ff00) << 8 )  | ( (i & 0x000000ff) << 24 )

i 的字节序说明:按照从左到右的顺序,把 i 的第一个字节右移 3 个字节( 24 bit ),第二个字节右移 1 字节 ( 8 bit ),第三个字节左移 1 字节 ( 8 bit ),第四个字节左移 3 个字节 ( 24 bit )

在实际的程序处理中,不应该出现字节序的问题,只有 “网络字节序”“主机字节序” ,需要转换字节序时,使用 ntohl, ntohs, htonl, htons 等函数即可

ntohl       # uint32 类型 网络序转主机序
htonl       # uint32 类型 主机序转网络序

ntohs       # uint16 类型 网络序转主机序
htons       # uint16 类型 主机序转网络序

小结

本文详述了字节序的一些知识,开发网络应用的时候会涉及到字节序的问题,所以,花点儿时间弄明白还是很有必要的

SAP物料分类账实战:从配置到月结的关键步骤(基于S/4HANA1909) 本文详细解析了在SAP S/4HANA 1909系统中,物料分类账从基础配置到月结操作的全流程。作为成本核算的核心,物料分类账通过多级价格确定实现实际成本核算,关键步骤包括激活物料分类账、配置自动过账科目(OBYC)、运行CKMLCP进行差异分摊与结算。文章旨在帮助财务与成本会计人员确保成本差异的准确归集与分摊,顺利完成月结。 阅读详情

相关推荐

《Zephyr OS 入门与实战》第3章:第一个 Zephyr 程序 - Blinky 实战

解决方法:确认设备树overlay文件已正确加载。返回值,确认驱动初始化状态。

2301_79143213的博客 512

精度为12位的数据c语言,浮点数表示法-C语言

浮点数表示法任何数据在内存中都是以二进制(1或着0)顺序存储的,每一个1或着0被称为1位,而在x86CPU上一个字节是8位。比如一个16位(2字节)的short int型变量的值是1156,那么它的二进制表达就是:00000100 10000100。由于Intel CPU的架构是Little Endian(请参照计算机原理相关知识),所以它是按字节倒序存储的,那么就应该是这样:10000100 0...

weixin_39663593的博客 988

高通拨号流程介绍

本文介绍了高通平台(如SDX55)中APSS(A7处理器)与ModEM(Q6处理器)间的通信机制。

四儿家的小祖宗的博客 1029

C语言有符号 存储,有符号数在计算机中的存储及在C语言中的运用

前言:近期在调试一个博世的三轴加速度传感器时,在用c写有符号数相关的运算和操作相关的代码时,进一步去理解了有符号数的应用。首先在阅读相关文档时,发现了对寄存器描述中出现Two's complement,实际是为了说明该寄存器读出的值是以补码的形式存储,假设有两个八位寄存器,第一个寄存器中有低四位(LSB)和第二个寄存器有高八位(MSB)组成了一个12位的数据,这12位数据以补码的形式读出,其中最高...

weixin_36115496的博客 589

别再只背Top10了!用DVWA靶场实战复现SQL注入、XSS和CSRF(附详细Payload)

本文通过DVWA靶场实战演练SQL注入、XSS和CSRF漏洞,帮助读者从理论走向实践。详细介绍了各类漏洞的Payload构造方法、自动化工具使用技巧以及防御措施,特别适合想要突破OWASP Top10理论局限的安全爱好者。文章包含从基础到高级的实战案例,是提升Web安全技能的实用指南。

weixin_30326515的博客 442

C语言中结构体的位域(bit-fields)

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为: struct 位域结构名 { 位域列表

一口Linux的专栏 1563

C语言中以12位输出是什么意思,c语言中“%nd”是什么意思?

d格式:用来输出十进制整数.有以下几种用法:%d:按整型数据的实际长度输出.%nd:n为指定的输出字段的宽度.如果数据的位数小于n,则左端补以空格,若大于n,则按实际位数输出.%ld:输出长整型数据.补充一点其他的:o格式:以无符号八进制形式输出整数.对长整型可以用"%lo"格式输出.同样也可以指定字段宽度用“%mo”格式输出.例:main(){ int a = -1;printf("%d,%o"...

weixin_42297904的博客 2179

C语言之基本数据类型和数

我们将会学习到算数类型和基本数据类型有哪些,并且学会不同进制数之间的相互转化。

我是一名小白,现在我们来一起创造出属于我们的故事吧! 1193

理解字节序 大端字节序和小端字节序

以下内容参考了 http://www.ruanyifeng.com/blog/2016/11/byte-order.html https://blog.csdn.net/yishengzhiai005/article/details/39672529 1. 计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。 举例来说,数值0x2211使用两个字节储存:高位字节是0x22,低位字节是0x11。 大端字节序:高位字节在前,低位字节在后

一颗橙 8238

理解字节序

理解字节序

《好好先生》专栏 217

小端字节序记忆理解

小端字节序记忆理解

皇天惊虞的博客 158

字节序理解与分析

字节序 什么是字节序字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。 常见的字节序 大端字节序(Big Endian):将多个字节值的最高有效字节储存于较低的内存位置。在大端处理器的机器上,数值0xABCD1234在内存存储为连续字节0xAB、0xCD、0x12、0x34。 小端字节序(Little endian):将多个字节值的最低有效字节存储于较低的内存位置。比如在小段处理器的机器上,数值0xABCD1234在内存中存储为连续的字节0x34、0x12、0xCD、0x34

1756

理解大小端字节序

学过编程的人都应该知道大小端字节序的概念,但是很多时候,总是把他们弄混,这是整理出来的一份很简单的方式理解字节序的文章,废话不多说,这里直接入正题。什么是字节序?    字节序,简单来说,就是指的超过一个字节的数据类型在内存中存储的顺序        那么就很明显了,像char这样的类型,肯定不存在字节序的问题了。字节序分为哪几类?大端字节序:     高位字节数据存放在低地址处,低位数据存放在高...

架构师的成长之路的博客 4778

java 大小端字节序_理解大小端字节序

学过编程的人都应该知道大小端字节序的概念,但是很多时候,总是把他们弄混,这是整理出来的一份很简单的方式理解字节序的文章,废话不多说,这里直接入正题。什么是字节序字节序,简单来说,就是指的超过一个字节的数据类型在内存中存储的顺序那么就很明显了,像char这样的类型,肯定不存在字节序的问题了。字节序分为哪几类?大端字节序:高位字节数据存放在低地址处,低位数据存放在高地址处;小段字节序:高位字节数据存...

weixin_30015835的博客 905

大小端字节序理解及判断以及地址理解

大小端字节序理解及判断以及地址理解

qq_74011656的博客 171

linux内核:理解大小端字节序

给一个十进制整数,123456,很明显左边的是高位,右边的是低位。其实字节序只有大端字节序和小端字节序两种,网络字节序也是大端,这个以后会说到。关于大小端字节序的重点,上面已经标的很明显了,一个是高低地址,一个是高低位字节,那下面就看看这两个是什么意思?学过编程的人都应该知道大小端字节序的概念,但是很多时候,总是把他们弄混,这是整理出来的一份很简单的方式理解字节序的文章,废话不多说,这里直接入正题。字节序,简单来说,就是指的超过一个字节的数据类型在内存中存储的顺序。TCP/IP协议传输数据时,字节序默认。

m0_74282605的博客 687

彻底理解大端字节序、小端字节序与网络字节序

摘要: 字节序指多字节数据在内存中的存储顺序,分为大端(高位字节在低地址)和小端(低位字节在低地址)。网络通信统一采用大端字节序(网络字节序)以确保跨平台兼容。实际应用中,需通过htonl、ntohl等函数转换主机序与网络序。字节序影响网络编程、二进制文件处理及数据解析,理解其原理(如小端仅字节顺序反转)是避免数据错乱的关键。记忆口诀:“小端低字节先存,大端高字节先存”。

qq_35803412的博客 2233

字节序理解

字节序(Byte Order),也称为字节顺序或端序,指的是在计算机内存中如何存储多字节数据类型(如整数、浮点数等)中的字节。根据字节的排列顺序,主要有两种类型的字节序:大端序(Big-Endian)和小端序(Little-Endian)。

m0_73640344的博客 1078

字节序 高低地址和高低位及java modbus 字节序中的理解

理解几个概念 1字节序 多个字节 之间排列的顺序 2字节高低位 例如16进制 0x12345678 占用了4个字节 那么1234就是高位 5678就是低位 3内存高低地址 数据存在在内存中时 需要先划分分出一个区域给数据保存 栈底 (高地址) ---------- buf[3] buf[2] buf[1] buf[0] ---------- 栈顶 (低地址) 那么数据存储就会有多种方式保存 最常用的就是 大端和小端 小端 a) Little-Endian就是低位字节排放在内存的低地址

qq_29035793的博客 4456

基于SpringBoot+Vue的外卖点餐系统(源码+部署说明+系统介绍).zip

基于SpringBoot+Vue的外卖点餐系统是一个集成了前端和后端技术的外卖订餐平台,主要用于商家和用户的外卖点餐和管理。该系统的源码、部署说明和系统介绍已经打包成一个zip文件,方便用户使用。该系统的前端部分采用了Vue框架进行开发,主要实现了用户界面和交互,包括登录、注册、商品列表、购物车、订单管理等功能。而后端部分则采用了SpringBoot框架,负责处理用户请求、管理用户数据并提供相应的API接口。该系统可以方便地进行外卖点餐和管理,商家可以方便地管理商品信息、订单信息等,用户可以方便地查询商品信息、下单购物等。同时,该系统还支持对用户权限的管理,可以对不同用户进行分组和授权,保证信息的安全性。对于小餐厅商家而言,该系统可以方便地管理商品信息、订单信息等,提高了商家管理效率和准确性。对于消费者而言,该系统可以方便快捷地查询商品信息、下单购物,提高了消费者的就餐体验和方便性。同时,对于开发者而言也是一个学习Vue和SpringBoot技术的不错案例,值得一试。总之,基于SpringBoot+Vue的外卖点餐系统是一个功能齐全、易用、实用性很高的外卖订餐平台,能够方便地进行外卖点餐和管理,提高了商家管理效率和顾客的就餐体验。同时,对于开发者而言也是一个学习Vue和SpringBoot技术的不错案例,值得一试。

burp2.011.zip

burp

上一篇: 异或运算常见的应用
下一篇: 让人疑惑的C语言位域
Linux开发那些事儿
博客等级 码龄10年 32粉丝 · 52原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值