0

0

Go语言中实现字节序处理:encoding/binary包解析无符号16位整数

花韻仙語

花韻仙語

发布时间:2025-10-30 14:38:25

|

659人浏览过

|

来源于php中文网

原创

Go语言中实现字节序处理:encoding/binary包解析无符号16位整数

本文深入探讨go语言中如何使用`encoding/binary`包高效处理字节数据,特别是针对无符号16位整数的读写操作。通过`bigendian`和`littleendian`接口,可以轻松实现类似node.js `buffer`的`readuint16be`功能,确保跨平台数据交换的字节序兼容性。

在进行跨系统通信、处理二进制文件或网络协议时,经常需要从字节序列中提取特定类型的数据,例如无符号16位整数(uint16)。由于不同系统可能采用不同的字节序(Endianness),这要求我们在处理时进行明确的指定。Node.js的Buffer对象提供了readUInt16BE等便捷方法来处理这类需求。在Go语言中,encoding/binary包提供了强大且灵活的工具来应对此类字节序相关的操作。

Go语言中的字节序处理核心:encoding/binary包

Go语言的encoding/binary包是处理字节序列与Go原生数据类型之间转换的关键。它定义了ByteOrder接口,并提供了两个主要的实现:BigEndian(大端字节序)和LittleEndian(小端字节序)。通过这两个接口,我们可以方便地进行数据的编码(将Go类型写入字节切片)和解码(从字节切片读取到Go类型)。

一个uint16类型的数据占用两个字节。在进行读写操作时,我们需要提供一个足够大的字节切片([]byte)作为数据的源或目标。

读取无符号16位整数 (Uint16)

要从字节切片中读取一个uint16值,可以使用binary.BigEndian.Uint16()或binary.LittleEndian.Uint16()方法。这些方法接受一个字节切片作为参数,并从该切片的前两个字节中,按照指定的字节序解析出uint16值。

立即学习go语言免费学习笔记(深入)”;

例如,Node.js中Buffer的buf.readUInt16BE(offset)功能,其作用是从缓冲区buf的指定offset位置开始,以大端字节序读取一个无符号16位整数。在Go语言中,这可以等价地通过binary.BigEndian.Uint16(buf[offset:])来实现。

写入无符号16位整数 (PutUint16)

反之,如果需要将一个uint16值写入到字节切片中,则可以使用binary.BigEndian.PutUint16()或binary.LittleEndian.PutUint16()方法。这些方法接受一个字节切片和一个uint16值作为参数,将该值按照指定的字节序写入到切片的前两个字节中。

Cutout.Pro
Cutout.Pro

AI驱动的视觉设计平台

下载

在执行写入操作之前,务必确保目标字节切片从指定的偏移量开始有至少两个字节的可用空间,以避免运行时错误。

完整示例代码

以下Go语言示例演示了如何在字节切片中写入和读取无符号16位整数,涵盖了大端和小端字节序的处理过程:

package main

import (
    "encoding/binary"
    "fmt"
)

func main() {
    // 创建一个足够大的字节切片作为缓冲区,模拟数据传输或存储场景
    buf := make([]byte, 1024)

    // --- 大端字节序 (Big Endian) 示例 ---
    // 假设我们要将 uint16 值 320 写入到 buf 的偏移量 127 处,采用大端字节序。
    // 320 的十六进制表示为 0x0140。在大端序中,高位字节 0x01 在前,低位字节 0x40 在后。
    offsetBE := 127
    binary.BigEndian.PutUint16(buf[offsetBE:], 320)
    fmt.Printf("写入大端值 %d 到 buf[%d:],字节表示: %v (十进制)\n", 320, offsetBE, buf[offsetBE:offsetBE+2])

    // 从 buf 的偏移量 127 处读取 uint16 值,采用大端字节序。
    resultBE := binary.BigEndian.Uint16(buf[offsetBE:])
    fmt.Printf("从 buf[%d:] 读取大端值: %d\n\n", offsetBE, resultBE)

    // --- 小端字节序 (Little Endian) 示例 ---
    // 假设我们要将 uint16 值 420 写入到 buf 的偏移量 255 处,采用小端字节序。
    // 420 的十六进制表示为 0x01A4。在小端序中,低位字节 0xA4 在前,高位字节 0x01 在后。
    offsetLE := 255
    binary.LittleEndian.PutUint16(buf[offsetLE:], 420)
    fmt.Printf("写入小端值 %d 到 buf[%d:],字节表示: %v (十进制)\n", 420, offsetLE, buf[offsetLE:offsetLE+2])

    // 从 buf 的偏移量 255 处读取 uint16 值,采用小端字节序。
    resultLE := binary.LittleEndian.Uint16(buf[offsetLE:])
    fmt.Printf("从 buf[%d:] 读取小端值: %d\n\n", offsetLE, resultLE)

    // 验证缓冲区中特定位置的字节状态
    fmt.Printf("缓冲区中偏移量 %d 处的原始字节: %v\n", offsetBE, buf[offsetBE:offsetBE+2])
    fmt.Printf("缓冲区中偏移量 %d 处的原始字节: %v\n", offsetLE, buf[offsetLE:offsetLE+2])
}

代码输出示例:

写入大端值 320 到 buf[127:],字节表示: [1 64] (十进制)
从 buf[127:] 读取大端值: 320

写入小端值 420 到 buf[255:],字节表示: [164 1] (十进制)
从 buf[255:] 读取小端值: 420

缓冲区中偏移量 127 处的原始字节: [1 64]
缓冲区中偏移量 255 处的原始字节: [164 1]

注意事项

在使用encoding/binary包处理字节数据时,以下几点至关重要:

  1. 缓冲区大小与越界: 确保你提供的字节切片([]byte)从指定的偏移量开始有足够的空间来存储或读取所需的数据类型。例如,uint16需要2个字节。如果切片长度不足,PutUint16或Uint16等方法可能会导致运行时错误(panic),因为它们不会进行边界检查并返回错误。
  2. 精确的偏移量管理: 在处理复杂二进制数据结构时,精确计算和管理字节切片中的偏移量至关重要。错误的偏移量会导致读取或写入不正确的数据,甚至访问到切片以外的内存区域。
  3. 字节序一致性: 在进行跨系统、跨语言或跨协议的数据交换时,必须确保数据的写入方和读取方使用相同的字节序。如果写入时使用大端字节序,读取时也应使用大端字节序,反之亦然。字节序不一致将导致数据解析错误,获取到错误的值。
  4. Uint16和PutUint16的错误处理: binary.BigEndian.Uint16()和binary.BigEndian.PutUint16()(以及它们的小端对应版本)是直接操作字节切片的方法,它们不返回错误。这意味着调用者有责任确保传入的切片是有效且足够长的。对于更复杂的场景,例如从io.Reader接口读取数据或写入io.Writer接口,可以使用binary.Read()和binary.Write()函数,这些函数会返回错误,从而允许进行更健壮的错误处理。

总结

encoding/binary包是Go语言处理二进制数据和字节序转换的强大且高效的工具。通过BigEndian和LittleEndian接口提供的Uint16和PutUint16方法,我们可以轻松地在Go程序中实现对无符号16位整数的精确读写,完美替代或实现类似Node.js Buffer的readUInt16BE等功能。深入理解并正确应用字节序的概念是确保数据完整性、实现跨平台兼容性以及构建健壮二进制数据处理逻辑的关键。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

310

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

539

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

21

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

28

2026.01.06

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1155

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

213

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1936

2025.12.29

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.6万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号