用于 SMS PDU 的 7 位用户数据编码/解码(PDU 位打包器)





5.00/5 (10投票s)
一个根据 GSM 03.38 标准打包/解包 SMS 7 位用户数据的库。
引言
大多数开发发送 SMS 应用程序的开发人员最终会遇到将 SMS 文本编码为 7 位打包字节的问题。我在网上找到了很多尝试解决此问题的方法和实现,但实际有效的那些要么有错误,要么存在严重的性能问题。
我正在开发的 SMS 应用程序旨在每天发送和接收数百万条 SMS,因此我需要的是一个简单、易用且高性能的 7 位 PDU 打包和解包库。我开发了 7 位 PDU 打包库,并想与其他开发人员分享,以便他们可以将宝贵的时间投入到其他方面,例如改进他们的应用程序、解决其他问题,或者只是与家人或朋友共度美好时光。
打包和解包
SMS 文本(用户数据)最常见的文本编码是 GSM 编码(7 位)和 Unicode(16 位)。GSM 编码通常用于拉丁语(英语、德语、西班牙语等)文本消息,其中每个字符仅使用 7 位表示。GSM 编码可以映射 128 个拉丁字符。
SMS 的用户数据部分保存编码的文本数据。根据 GSM 03.38,用户数据最多可以保存 140 字节。当使用 GSM 编码时,7 位字符必须打包成 8 位字节。这允许 SMS 在其用户数据字段中保存 160 个拉丁字符。
一个字符的 7 位二进制表示称为septet (七位字节),8 位二进制表示称为octet (八位字节)。
将 septet (七位字节,7 位字符) 填充到 octet (八位字节,8 位字节) 中的过程称为打包。相反的过程称为解包,这意味着从打包的数据中提取 septet (七位字节)。
打包协议
理解如何将 septet (七位字节) 打包到 octet (八位字节) 的最佳方法是通过示例。以下步骤将描述如何根据 GSM 编码打包文本“12345678”
第一步:根据 GSM 字符表将文本转换为 septet (七位字节)

第二步:将下一个 septet (七位字节) 的最低有效位移动到当前 septet (七位字节) 以创建 octet (八位字节)

最终结果将如下所示

第三步:通过用零填充,将最后一个字节的位补全到 8 位。
解包过程与打包过程完全相反。
使用库
该库封装在 PduBitPacker 类中。该库包含的方法有
PackBytes
: 根据 GSM 协议将未打包的 7 位数组打包为 8 位打包数组。此方法有 3 个重载。UnpackBytes
: 根据 GSM 协议将打包的 8 位数组解包为 7 位未打包数组。ConvertHexToBytes
:这是一个实用方法,可将十六进制字符串转换为字节数组。ConvertBytesToHex
: 这是一个实用方法,可将字节数组转换为十六进制字符串。

打包示例
// Filling the array with demo data to be packed
// The byte array is the GSM default encoding character codes for the following text:
// "12345678"
byte[] unpackedBytes = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 };
// Pack the bytes
byte[] packedBytes = PduBitPacker.PackBytes(unpackedBytes);
// Display the output as a hex string
MessageBox.Show(PduBitPacker.ConvertBytesToHex(packedBytes));

解包字节的示例:
// Fill the array with the packed bytes
byte[] packedBytes = PduBitPacker.ConvertHexToBytes("31D98C56B3DD70");
// Unpack the bytes
byte[] unpackedBytes = PduBitPacker.UnpackBytes(packedBytes);
// Display the output as a hex string
MessageBox.Show(PduBitPacker.ConvertBytesToHex(unpackedBytes));

参考文献
-
ETSI: http://etsi.org
-
了解 SMS (PDF): http://mobileforensics.files.wordpress.com/2007/06/understanding_sms.pdf
-
PDU 7 位文本编码示例: http://www.dreamfabric.com/sms/hello.html
-
GSM 字符表: http://www.dreamfabric.com/sms/default_alphabet.html