0

0

Go语言字符字节数值化与ASTM校验和计算教程

心靈之曲

心靈之曲

发布时间:2025-11-29 21:42:16

|

224人浏览过

|

来源于php中文网

原创

Go语言字符字节数值化与ASTM校验和计算教程

本文深入探讨go语言中如何进行字符和字节的数值运算,特别是针对十六进制求和的常见误区。通过解析字符字面量和字符串字节的底层数值表示,并结合实际案例——astm校验和的计算,展示了如何在go中高效、准确地处理这类数据,以实现数据完整性校验。

在Go语言中,进行字符和字节的数值运算是数据处理中常见的需求,尤其是在处理协议数据、校验和计算等场景。理解Go如何表示和操作字符及字节的数值是关键。

Go语言中字符与字节的数值表示

Go语言对字符和字节的处理方式非常直观。

  1. 字符字面量 (Rune): 在Go中,用单引号括起来的字符字面量,例如'a',其类型是rune。rune是int32的别名,它代表一个Unicode码点。这意味着'a'实际上代表了其ASCII/Unicode值97(十六进制为0x61)。因此,可以直接对rune类型的变量进行数值运算。

    例如,要将字符'a'的数值加上1,并得到结果字符'b',可以这样做:

    package main
    
    import "fmt"
    
    func main() {
        // 'a' 的码点值是 0x61 (十进制 97)
        val := 'a' // val 的类型是 rune (int32)
    
        // 将 0x61 加上 0x01,结果为 0x62 (十进制 98)
        // 然后将结果的数值转换回字符类型
        fmt.Printf("字符 '%c' 的数值加上 1 后为 '%c'\n", val, val+0x01) // 输出 'b'
        fmt.Printf("其数值表示为 %d (0x%X)\n", val+0x01, val+0x01)
        fmt.Printf("将数值转换回字符串: %v\n", string(val+0x01)) // 转换为字符串 "b"
    }

    输出结果:

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

    字符 'a' 的数值加上 1 后为 'b'
    其数值表示为 98 (0x62)
    将数值转换回字符串: b

    通过上述示例可以看出,'a' + 0x01直接进行了数值加法。

  2. 字符串的字节 (Byte): 当通过索引访问字符串时,例如s[i],返回的是一个byte类型的值。byte是uint8的别名,它代表字符串在特定位置的原始字节值。对于ASCII字符,byte值与rune值相同。因此,byte类型的值也可以直接参与数值运算。

    需要注意的是,fmt.Sprintf("%x", "a")这种方式是将字符串"a"格式化为它的十六进制表示字符串"61",结果是一个字符串。字符串之间进行+操作是拼接,而不是数值相加,因此不能直接用"61" + 0x01进行数值运算。

实际应用:ASTM校验和计算

理解了字符和字节的数值特性后,我们可以将其应用于实际场景,例如计算ASTM校验和。ASTM(美国材料与试验协会)校验和是一种简单的数据完整性检查机制,常用于实验室仪器数据传输协议中。

ImgGood
ImgGood

免费在线AI照片编辑器

下载

ASTM校验和的计算规则通常如下:

  • 遍历数据帧中的每个字节。
  • 将每个字节的数值累加到一个总和中。
  • 如果遇到STX(Start of Text,通常为0x02),则将累加和清零,重新开始计算。
  • 如果遇到ETX(End of Text,通常为0x03)或ETB(End of Transmission Block,通常为0x17),则停止累加。
  • 最终的总和通常以两位大写十六进制字符串的形式返回。

下面是Go语言实现ASTM校验和计算的示例代码:

package main

import (
    "fmt"
)

// 定义ASTM协议中常用的控制字符常量
const (
    ETX = 0x03 // End of Text
    ETB = 0x17 // End of Transmission Block (十进制 23)
    STX = 0x02 // Start of Text
)

// ASTMCheckSum 计算给定数据帧的ASTM校验和
func ASTMCheckSum(frame string) string {
    var sumOfChars uint8 // 使用 uint8 确保和在字节范围内

    // 遍历字符串中的每个字节
    for i := 0; i < len(frame); i++ {
        byteVal := frame[i] // 获取当前位置的字节值 (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() {
    // 示例ASTM数据帧,包含控制字符和实际数据
    data := "\x025R|2|^^^1.0000+950+1.0|15|||^5^||V||34001637|20080516153540|20080516153602|34001637\r\x033D\r\n"

    // 计算并打印校验和
    checksum := ASTMCheckSum(data)
    fmt.Printf("数据帧的ASTM校验和为: %s\n", checksum) // 预期输出 3D
}

输出结果:

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

数据帧的ASTM校验和为: 3D

在这个ASTMCheckSum函数中:

  • 我们定义了STX、ETX、ETB三个常量,它们直接使用十六进制数值表示。
  • sumOfChars变量被声明为uint8,以确保校验和的累加操作在单个字节的范围内进行,自动处理溢出(例如,255 + 1会变成0)。
  • 循环遍历frame字符串,frame[i]直接获取到每个字节的uint8值,可以直接参与加法运算。
  • 根据ASTM协议的规则,对STX、ETX、ETB进行特殊处理。
  • 最后,使用fmt.Sprintf("%02X", sumOfChars)将计算得到的uint8校验和格式化为两位大写的十六进制字符串。%02X确保输出总是两位,不足两位时前面补零。

注意事项

  1. Rune 与 Byte 的区别: 尽管在ASCII字符范围内rune和byte的数值可能相同,但它们代表的含义和使用场景不同。rune代表Unicode码点,可以表示多字节字符;byte代表单个字节,通常用于处理原始二进制数据或UTF-8编码的单个字节。在处理字符串时,如果涉及到非ASCII字符,len(s)返回的是字节数,而for _, r := range s则会按rune(字符)迭代。
  2. 编码问题: 在处理字符串并将其字节化时,始终要考虑字符串的编码。Go字符串默认是UTF-8编码。对于ASTM这类通常基于ASCII的协议,直接按字节处理通常没有问题。但如果数据源是其他编码,可能需要先进行解码。
  3. 数值类型选择: 在进行校验和或其他数值累加时,选择合适的数值类型(如uint8, uint16, uint32等)非常重要,这取决于协议规范中校验和的位数和范围。uint8适合单字节校验和,因为它会在255之后自动归零。

总结

Go语言通过其简洁的类型系统,使得字符和字节的数值运算变得直观且高效。字符字面量直接表示其Unicode码点,而字符串索引则提供原始字节值,两者都可以直接参与数值计算。通过理解这些基本特性,我们可以轻松地实现如ASTM校验和这类复杂的数据处理逻辑,从而确保数据传输的完整性和准确性。在实际开发中,正确区分字符的数值表示和其十六进制字符串表示,是避免常见错误的关键。

相关专题

更多
java基础知识汇总
java基础知识汇总

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

1465

2023.10.24

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

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

256

2023.08.03

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

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

208

2023.09.04

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

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

1465

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

619

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

550

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

545

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

161

2025.07.29

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

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

8

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号