Go语言解析SMS PDU编码:从AT指令获取的十六进制字符串到可读短信内容

3次阅读

Go语言解析SMS PDU编码:从AT指令获取的十六进制字符串到可读短信内容

本文介绍如何使用go语言直接解析gsm sms pdu格式数据,包括从at指令(如at+cmgl=4)返回的十六进制pdu字符串解码为发件人、接收人、时间戳和短信正文,并提供完整可运行示例及关键注意事项。

本文介绍如何使用go语言直接解析gsm sms pdu格式数据,包括从at指令(如at+cmgl=4)返回的十六进制pdu字符串解码为发件人、接收人、时间戳和短信正文,并提供完整可运行示例及关键注意事项。

在嵌入式通信、iot网关或Modem管理场景中,常需通过串口发送AT指令(如AT+CMGF=0切换为PDU模式,再执行AT+CMGL=4读取所有短信)获取原始PDU字符串。这类字符串(例如0791361907002039040C9136198748701300005150713220052308C8303A8C0EA3C3)是十六进制编码的二进制协议数据,无法直接阅读。幸运的是,Go生态已有成熟、轻量且符合3GPP TS 23.040规范的第三方库支持完整解析。

推荐使用 github.com/xlab/at/sms —— 它专为AT指令交互场景设计,完整实现SMS PDU的读取(ReadFrom)、编码(WriteTo)与字段映射,支持GSM 7-bit、UCS2(UTF-16BE)编码、TP-UDHI标志、状态报告等核心特性。

以下是一个最小可运行示例:

package main  import (     "encoding/hex"     "fmt"     "log"      "github.com/xlab/at/sms" )  func main() {     // 来自 AT+CMGL=4 响应的 PDU 十六进制字符串(不含行首 +CMGL:...)     pduHex := "0791361907002039040C9136198748701300005150713220052308C8303A8C0EA3C3"      // 解码为字节切片     pduBytes, err := hex.DecodeString(pduHex)     if err != nil {         log.Fatal("PDU hex decode failed:", err)     }      // 初始化 SMS 消息结构体并解析     msg := new(sms.Message)     if _, err := msg.ReadFrom(pduBytes); err != nil {         log.Fatal("PDU parsing failed:", err)     }      // 输出结构化信息     fmt.Printf("Sender: %sn", msg.Sender)     fmt.Printf("Recipient: %sn", msg.Recipient)     fmt.Printf("Timestamp: %vn", msg.Timestamp)     fmt.Printf("Content: %sn", msg.Text)     fmt.Printf("IsDeliver: %tn", msg.IsDeliver)     fmt.Printf("IsStatusReport: %tn", msg.IsStatusReport) }

运行后输出类似:

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

Sender: +639170000293 Recipient: +639178840731 Timestamp: 2015-05-07 17:32:20 +0000 UTC Content: Hahahaha IsDeliver: true IsStatusReport: false

关键注意事项

  • sms.Message.ReadFrom() 期望输入为原始PDU字节流(即已由hex.DecodeString()转换后的[]byte),而非原始十六进制字符串;
  • PDU可能包含状态报告(TP-MTI = 0x05)或长短信分段(TP-UDHI = 1),该库会自动识别并填充对应字段(如UserDataHeader);
  • 若短信含中文等Unicode字符,PDU通常使用UCS2编码(TP-DCS = 0x08),库会自动按UTF-16BE解码,无需手动处理;
  • 实际项目中建议配合串口库(如github.com/tarm/serial)封装AT指令交互逻辑,将AT+CMGL响应中的PDU部分提取后统一解析;
  • 该库不依赖CGO,纯Go实现,兼容交叉编译(如ARM嵌入式设备)。

综上,Go完全胜任SMS PDU解析任务——无需调用外部工具或Python脚本,借助成熟库即可在服务端或边缘设备中高效、可靠地完成短信内容提取与结构化处理。

text=ZqhQzanResources