0

0

Go语言中字符与字节的十六进制运算及ASTM校验和实现指南

霞舞

霞舞

发布时间:2025-11-29 22:29:00

|

362人浏览过

|

来源于php中文网

原创

Go语言中字符与字节的十六进制运算及ASTM校验和实现指南

本文旨在解决go语言中字符与十六进制数值运算的常见困惑,并提供实用的解决方案。文章首先阐述如何在go中对字符进行直接的算术运算以获取其ascii/unicode码点并进行加减。随后,重点介绍如何基于字节值实现astm校验和算法,包括特殊控制字符的处理逻辑和最终结果的十六进制格式化输出。通过具体代码示例,帮助读者理解并应用这些技术。

在Go语言中进行字符或字节的算术运算,尤其是涉及十六进制表示时,开发者常会遇到一些概念上的混淆。一个常见的误区是将十六进制的字符串表示(如"61")与其实际的数值(如0x61)等同起来进行算术操作。本教程将深入探讨如何在Go中正确地处理字符的数值运算,并以此为基础,详细讲解如何实现一个典型的字节校验和算法——ASTM校验和。

字符的直接算术运算

Go语言中的字符字面量(例如'a')实际上是rune类型,它是int32的别名,用于表示Unicode码点。这意味着你可以直接对字符字面量进行算术运算,而无需显式地将其转换为十六进制字符串再尝试解析。当一个rune或byte类型的值参与算术运算时,它会作为其底层整数值进行操作。

例如,如果你想将字符'a'的码点值增加0x01,你可以这样做:

package main

import "fmt"

func main() {
    // 获取字符 'a' 的码点值,即 0x61 (十进制 97)
    val := 'a' // val 的类型是 rune (int32)

    // 将 0x61 加上 0x01,结果为 0x62 (十进制 98)
    // 然后将结果转换回字符,0x62 对应的字符是 'b'
    fmt.Printf("%v\n", string(val + 0x01))
}

输出结果:

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

b

在这个例子中,'a'被视为其ASCII/Unicode码点值97(即0x61)。当加上0x01后,结果是98(即0x62)。最后,通过string()类型转换,将这个整数值解释为对应的字符'b'。这种方法直接且高效,避免了不必要的字符串转换和解析。

实现ASTM校验和

ASTM校验和是一种在数据传输中常用的简单校验机制,它通过对数据帧中的字节值进行累加来生成一个校验码。在ASTM协议中,校验和的计算有特定的规则,例如遇到STX(Start of Text)字符时重置累加和,以及在遇到ETX(End of Text)或ETB(End of Transmission Block)字符时停止累加。

以下是在Go语言中实现ASTM校验和的详细步骤和代码示例:

LangChain
LangChain

一个开源框架,用于构建基于大型语言模型(LLM)的应用程序。

下载

1. 定义控制字符常量

ASTM协议使用特定的控制字符来标记数据帧的开始和结束。在Go中,我们可以将这些字符定义为常量,以便代码更具可读性。

const (
    ETX = 0x03 // End of Text (文本结束符)
    ETB = 0x17 // End of Transmission Block (传输块结束符,十进制23)
    STX = 0x02 // Start of Text (文本开始符)
)

这些常量使用十六进制表示,直接对应它们的ASCII码值。

2. 编写校验和计算函数

ASTMCheckSum函数将接收一个字符串作为输入,并返回计算出的两位十六进制校验和。

package main

import (
    "fmt"
)

const (
    ETX = 0x03
    ETB = 0x17 // 23 decimal
    STX = 0x02
)

// ASTMCheckSum 计算给定字符串的ASTM校验和
func ASTMCheckSum(frame string) string {
    var sumOfChars uint8 // 使用 uint8 存储累加和,确保结果在 0-255 范围内

    // 遍历字符串中的每个字节
    for i := 0; i < len(frame); i++ {
        byteVal := frame[i] // frame[i] 返回的是 byte 类型 (即 uint8)

        // 累加当前字节的值
        sumOfChars += byteVal

        // 根据ASTM协议规则处理特殊字符
        if byteVal == STX {
            // 如果遇到 STX,重置累加和
            sumOfChars = 0
        }

        if byteVal == ETX || byteVal == ETB {
            // 如果遇到 ETX 或 ETB,停止累加并跳出循环
            break
        }
    }

    // 将最终的累加和格式化为两位大写十六进制字符串
    return fmt.Sprintf("%02X", sumOfChars)
}

func main() {
    // 示例数据帧,包含 STX (\x02) 和 ETX (\x03)
    data := "\x025R|2|^^^1.0000+950+1.0|15|||^5^||V||34001637|20080516153540|20080516153602|34001637\r\x033D\r\n"
    fmt.Println(ASTMCheckSum(data))
}

代码解析:

  • sumOfChars uint8: 我们使用uint8类型来存储累加和。byte在Go中是uint8的别名,其值范围是0到255。这意味着当累加和超过255时,它会自动“环绕”(overflow),这在校验和计算中是常见的行为,因为它通常只关心低八位。
  • for i := 0; i : 循环遍历输入字符串frame的每一个字节。frame[i]直接返回对应位置的byte值。
  • sumOfChars += byteVal: 将当前字节的值累加到sumOfChars中。
  • if byteVal == STX { sumOfChars = 0 }: 这是ASTM协议的关键规则之一。当遇到起始字符STX时,校验和的累加必须从零开始重新计算。
  • if byteVal == ETX || byteVal == ETB { break }: 同样,ASTM协议规定,当遇到结束字符ETX或ETB时,校验和的累加就停止了。因此,循环在此处中断。
  • fmt.Sprintf("%02X", sumOfChars): 最后,将计算得到的sumOfChars格式化为一个两位大写的十六进制字符串。%02X格式化动词确保输出总是两位,不足两位时前面补零(例如,0x0A会格式化为0A,0x0F会格式化为0F,而0x03会格式化为03)。

示例运行结果:

3D

这个结果与ASTM协议中预期的校验和一致,表明函数正确地实现了算法。注意,在main函数中,示例数据字符串使用了Go的十六进制转义序列\x02和\x03来表示STX和ETX控制字符。

注意事项与总结

  • 字符与字节的本质: 在Go语言中,理解rune(int32,用于Unicode码点)和byte(uint8,用于原始字节数据)的区别至关重要。直接对它们进行算术运算是获取其数值并进行操作的正确方式,而不是尝试将它们转换为十六进制字符串。
  • 校验和类型: 对于校验和这类通常只关心低八位(0-255)的计算,使用uint8类型来存储累加和是最佳实践,它能自然地处理溢出(wrap-around)行为,避免额外的模运算。
  • 字符串中的控制字符: 在Go字符串中表示非打印或控制字符时,可以使用十六进制转义序列(例如\x02)或Unicode转义序列(例如\u0002)。
  • 格式化输出: fmt.Sprintf提供了强大的格式化能力。对于将整数值格式化为特定长度的十六进制字符串,%02X是一个非常有用的模式。

通过本文的讲解和示例,读者应该能够清晰地理解Go语言中字符和字节的数值运算机制,并掌握如何根据特定协议(如ASTM)实现复杂的校验和计算。这些基础知识对于处理二进制数据、网络协议以及文件格式解析等任务都非常重要。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1463

2023.10.24

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

738

2023.08.22

字符常量是什么
字符常量是什么

字符常量是计算机编程中的一个概念,通常用于表示单个字符。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

261

2023.12.26

java中break的作用
java中break的作用

本专题整合了java中break的用法教程,阅读专题下面的文章了解更多详细内容。

118

2025.10.15

java break和continue
java break和continue

本专题整合了java break和continue的区别相关内容,阅读专题下面的文章了解更多详细内容。

255

2025.10.24

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

254

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.09.04

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

4

2026.01.15

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.7万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

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

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