首页 > 后端开发 > Golang > 正文

Golang中字符与十六进制运算及ASTM校验和计算

聖光之護
发布: 2025-11-29 23:07:02
原创
329人浏览过

Golang中字符与十六进制运算及ASTM校验和计算

本文深入探讨了在golang中如何进行字符与数值的转换及算术运算,特别是针对十六进制求和的常见误区。我们将首先澄清字符与字符串十六进制表示的区别,并演示正确的字符算术方法。随后,文章将详细介绍如何实现astm校验和(checksum)的计算,包括其核心逻辑和完整的go语言代码实现,旨在帮助开发者准确处理数据帧的校验需求。

Golang中的字符与数值运算

在Golang中,字符(character)本质上是整数类型。单个字符字面量,例如 'a',其类型是 rune(实际上是 int32 的别名,用于表示Unicode码点),而当它作为字符串中的一个字节被访问时,则是一个 byte(uint8 的别名)。这意味着我们可以直接对字符进行算术运算,因为它们代表的是其对应的ASCII或Unicode数值。

许多开发者在尝试对字符的“十六进制值”进行求和时,可能会误用 fmt.Sprintf("%x", "a") 这样的方法。然而,fmt.Sprintf("%x", "a") 的结果是一个字符串 "61",它仅仅是字符 'a' 的ASCII码(0x61)的字符串表示,而非一个可用于算术的数值。直接将字符串 "61" 与其他数值相加会导致类型错误。

正确的做法是直接使用字符的数值。例如,要将字符 'a' 的数值与 0x01 相加,并得到结果字符 'b',可以这样做:

package main

import "fmt"

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

    // 将 0x61 与 0x01 相加,结果为 0x62
    // 然后将数值 0x62 转换回字符,即 'b'
    fmt.Printf("%v\n", string(val + 0x01)) // 输出: b
}
登录后复制

这段代码展示了Go语言中字符与整数运算的直观性。字符 'a' 的底层数值是 97(十进制)或 0x61(十六进制),对其进行加法运算后,再通过 string() 转换回字符,即可得到预期的结果。

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

魔搭MCP广场
魔搭MCP广场

聚合优质MCP资源,拓展模型智能边界

魔搭MCP广场 96
查看详情 魔搭MCP广场

ASTM 校验和计算原理

ASTM(American Society for Testing and Materials)是一种广泛应用于医疗、工业等领域的数据传输标准。其定义的校验和(Checksum)是一种简单而有效的错误检测机制,用于确保数据在传输过程中的完整性。ASTM校验和的基本计算规则如下:

  1. 起始标志 (STX):当遇到 STX (Start of Text, 0x02) 字符时,校验和的累加器会被重置为零。
  2. 累加范围:校验和的计算通常包括 STX 之后到 ETX (End of Text, 0x03) 或 ETB (End of Transmission Block, 0x17) 之前的所有字符的字节值。
  3. 累加方式:将范围内每个字符的字节值累加到校验和中。
  4. 终止标志 (ETX/ETB):当遇到 ETX 或 ETB 字符时,累加过程停止。这些终止字符本身通常不包含在最终的校验和计算中,但它们标志着校验和计算的结束点。
  5. 结果:最终的校验和通常表示为一个两位十六进制数。

在Go语言中实现ASTM校验和

根据上述原理,我们可以实现一个 ASTMCheckSum 函数来计算给定字符串的ASTM校验和。我们需要定义一些常量来表示控制字符,并遍历输入字符串的字节,根据规则累加和处理。

package main

import (
    "fmt"
)

const (
    STX byte = 0x02 // Start of Text
    ETX byte = 0x03 // End of Text
    ETB byte = 0x17 // End of Transmission Block
)

// ASTMCheckSum 计算给定字符串的ASTM校验和
func ASTMCheckSum(frame string) string {
    var sumOfChars uint8 // 使用 uint8 确保和在 0-255 之间循环

    // 遍历字符串中的每个字节
    for i := 0; i < len(frame); i++ {
        byteVal := frame[i] // 获取当前字节值

        // 如果遇到 STX,重置校验和
        if byteVal == STX {
            sumOfChars = 0
        }

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

        // 如果遇到 ETX 或 ETB,停止累加并跳出循环
        if byteVal == ETX || byteVal == 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)) // 预期输出: 3D
}
登录后复制

在上述代码中:

  • 我们定义了 STX、ETX 和 ETB 为 byte 类型的常量,以便与字符串中的字节值直接比较。
  • sumOfChars 被声明为 uint8。这是一个关键点,因为 uint8 的最大值是 255。当累加的和超过 255 时,它会自动“溢出”并从 0 重新开始(例如 255 + 1 = 0),这正是许多校验和算法(包括ASTM)所需的模 256 运算效果。
  • 循环遍历 frame 字符串的每个字节。Go语言的字符串在迭代时,frame[i] 会直接返回对应位置的 byte 值。
  • 根据ASTM规则,如果遇到 STX,sumOfChars 会被重置。
  • 每个字节都被累加到 sumOfChars 中。
  • 一旦遇到 ETX 或 ETB,循环立即终止,不再处理后续字符。
  • 最后,使用 fmt.Sprintf("%02X", sumOfChars) 将 uint8 类型的校验和格式化为两位大写的十六进制字符串。%02X 确保输出始终是两位,不足两位时前面补零。

注意事项与总结

  1. 字符与字节的区别:在Go语言中,理解字符(rune)和字节(byte)以及它们与字符串表示形式(如十六进制字符串)之间的关系至关重要。直接对字符进行算术运算操作的是其底层数值,而不是其字符串形式。
  2. 校验和类型:选择正确的整数类型(如 uint8)对于实现模运算的校验和算法非常重要,它可以避免手动进行模运算。
  3. 控制字符处理:ASTM校验和算法对 STX、ETX 和 ETB 等控制字符有特殊处理规则(重置、终止),务必在实现中准确遵循。
  4. 编码一致性:当处理包含非ASCII字符的字符串时,确保所有参与校验和计算的系统都使用相同的字符编码(通常是UTF-8),以避免字节值不匹配的问题。

通过本文的讲解和示例,您应该能够清晰地理解Go语言中字符的数值运算,并掌握如何根据ASTM标准实现一个可靠的数据校验和计算功能。

以上就是Golang中字符与十六进制运算及ASTM校验和计算的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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