实践:二进制数据处理与封装

打印 上一主题 下一主题

主题 643|帖子 643|积分 1929

实践:二进制数据处理与封装

作者:哲思
时间:2022.8.4
邮箱:zhe__si@163.com
GitHub:zhe-si (哲思) (github.com)
前言

最近在研究所做网络终端测试的项目,包括一些嵌入式和底层数据帧的封装调用。之前很少接触对二进制原始数据的处理与封装,所以在此进行整理。
以下例子主要以 c++ 语言进行说明。
什么是二进制数据

在电脑上一切数据都是通过二进制(0或1)进行存储的,通过多位二进制数据可以进而表示整形、浮点型、字符、字符串等各种基础类型数据或者一些更复杂的数据格式。
针对日常中一般的需求进行编程,我们通常无需关注底层的二进制数据。但如果要处理二进制文件(音频、视频、图片等)、设计空间上更高效的数据结构(网络数据帧、字节码、protobuf)或者处理某些底层时,需要我们处理这些二进制数据。
计算机中,称每一个二进制位为比特(bit,也称:位),是计算机中的最小存储单位。
每 8 比特组成一个字节(byte),一般是计算机实际存储和处理的最小单位(可以是它的倍数),也就是说,计算机是以字节为最小单位分配空间或进行计算的,不能分配比字节更小的存储空间(如,最小的数据类型是char,长度 1 字节,不支持申请 6 比特存储空间)或者直接处理小于字节单位的数据(如,两个 4 比特的数据相加减)。
若干字节构成一个计算机字(简称:字,word),表示计算机一次性处理事务的固定长度二进制数据,字的位数为字长。计算机是以字为单位处理或运算的,两个常见的概念是CPU位数操作系统位数
CPU 的位数就是指 CPU 执行一次指令能处理的最大位数(一个字长),和 CPU 中的寄存器的位数对应。其中,地址寄存器 MAR 限制了计算机的寻址范围,数据寄存器 MDR 限制了一次处理的数据长度。更多的位数带来了更大的寻址空间和更强的运算能力。
说明:寻址范围不等于内存大小,寻址对象有内存条、显卡内存、声卡、网卡和其他设备。之所以常把寻址范围当作内存上限,是因为内存是CPU的主要寻址对象。
这里解释一下常见的指令架构:x86 是 intel 推出的一种指令集架构(复杂指令集 CISC 架构),一开始只有32位的,叫 x86_32;后来 AMD 公司推出了兼容 x86_32 的 64 位指令集 amd64,被业界接受,intel 将其改名为 x86_64,简称 x64,而 x86_32 和 x86_64 可统称为 x86。与 x86 相对的是基于精简指令集RISC架构的 ARM 指令集架构,多用于移动设备。
操作系统基于 CPU 指令集实现,所以操作系统位数也直接对应 CPU 位数。由于 CPU 指令集的向下兼容性,所以 32 位操作系统也可以运行在 64 位的 CPU 上,但反过来不行。操作系统对软件提供了向下兼容的能力,64 位的操作系统支持 64 和 32 位的程序,但 32 位的操作系统只支持 32 位的程序。
处理二进制数据

在大多语言中,最小的数据类型是 char,一个字节,二进制数据多用 unsigned char 表示,并写作 uint8。语言底层常把它当作 int 进行运算。
二进制常数以“0b”开头,如:0b001。二进制数据也常用8进制(以“0”开头)和 16 进制(以“0x”开头)表示,如:0257(175,八进制)、0x1f(31,16进制)。8 进制 1 个数字表示 3 位二进制数据,16 进制 1 个数字表示 4 位二进制数据,一个字节可以用 2 个 16 进制数表示。

若要处理小于一字节的数据,就要使用位运算符(&、|、^、~、>>、 5;// 此处以大端存储,获得offset要截取byte7的低5位作为高位,byte8作为低位,求和:先清空byte7前3位,保留后5位数据,把它移到高8位上,再通过全0的低8位与byte8按位求或来求二者之和((byte7 & 0b00011111)  data.size()) return default_value;    T value = 0;    for (int i = 0; i < valueSize; i++) {        if (ENDIAN) {            value |= (data & 0xff)
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

渣渣兔

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表