https://en.wikipedia.org/wiki/GSM_03.38
GSM 引入短信服务的时候,规范了相关的字符编码。
其中,定义了一个 7bit 的字符编码,支持英语和一些西欧语言,这套标准就是 GSM 03.38,也被称之为 3GPP 23.038,在移动通信技术领域之外,更广泛的称呼是 GSM-7 编码(gsm7bit)。
- PS:短信中如果要包含其他语言,必须使用 16 位 UCS-2 字符编码进行传输。
- PS:按照 GSM 03.40 标准(TP-Data-Coding-Scheme),一共支持三种编码(00 GSM7bit,01 8bit,02 UCS2)
- PS:3GPP 23.038 中还又定义一个 national language shift table,
可以通过相关代码在 GSM-7 的技术框架内支持一些语言,比如葡萄牙语、西班牙语、土耳其语等。
中文这种字符这么多的就别想了。
字符集
分析
-
算是可变长度编码,拓展区域字符需要用 ESC (
0x1B
) 开头,算两位长度。 -
ASCII 可打印字符中(Python
string.printable
),有四个不支持:` \t # TAB 水平制表符 \x0b # VT 垂直制表符 \x0c # FF 换页
-
GSM-7 基本兼容同为七位编码的 ASCII:
- ASCII 可打印字符中,有 8 个符号放在拓展区,
- 其他的和 GSM-7 编码完全相同。
^ ~ \ | { } [ ]
-
图中标黄色的 7 个字符说明:
- BCS:
- LF
\r
换行 - CR
\n
回车 - ESC
- SP
- LF
- EXT:
- FF 1B0A 对应 ASCII 0C 位置的换页符
- CR2 1B0D
- SS2 1B1B 保留
- BCS:
-
GSM-7 用控制字符换了以下 40 个字符:
'£', '¥', 'è', 'é', 'ù', 'ì', 'ò', 'Ç', 'Ø', 'ø', 'Å', 'å', 'Δ', 'Φ', 'Γ', 'Λ', 'Ω', 'Π', 'Ψ', 'Σ', 'Θ', 'Ξ', 'Æ', 'æ', 'ß', 'É', '¤', '¡', 'Ä', 'Ö', 'Ñ', 'Ü', '§', '¿', 'ä', 'ö', 'ñ', 'ü', 'à', '€',
对短信长度计算的影响
和 8bit 的 ASCII 编码方案相比:
- 利用那些没有用的控制位,支持更多语言(同时,牺牲了 8 个标点符号,需要两个字节表示)
- 140 * 8 / 7 = 160,也就是一条短信支持的字符数,从 140 提升到 160。
如果超出就按照 153 个字符切割,比如:
500 个 GSM-7 字符的短信,在通信过程中需要切割成 153 + 153 + 153 + 41 四条短信发出。
每条短信带一个头(附加信息),包含这批短信的总条数和当前这条短信的序号。
收信方根据短信的头信息来把这一批短信组装成一条,展示给用户。
参考:2018/06/08,短信长度到底是怎么规定的
填充位
根据协议:
如果剩余长度 1 ~ 6,最后的几位应该用 0 填充。
如果剩余长度位 7,为了避免和 0x00 @
混淆,应该用 0x0D 填充,也就是 \r
(回车)。
stat = {}
for i in range(1, 161):
stat.setdefault(8 - (i * 7 % 8), []).append(i)
pprint.pp(stat, width=160)
{1: [1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 113, 121, 129, 137, 145, 153],
2: [2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 122, 130, 138, 146, 154],
3: [3, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, 123, 131, 139, 147, 155],
4: [4, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 132, 140, 148, 156],
5: [5, 13, 21, 29, 37, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 141, 149, 157],
6: [6, 14, 22, 30, 38, 46, 54, 62, 70, 78, 86, 94, 102, 110, 118, 126, 134, 142, 150, 158],
7: [7, 15, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95, 103, 111, 119, 127, 135, 143, 151, 159],
8: [8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160]}
参考资料与拓展阅读
- https://www.infobip.com/docs/essentials/national-language-shift
- https://en.wikipedia.org/wiki/User_Data_Header
- https://itecspec.com/spec/3gpp-29-311-a-2-tp-data-coding-scheme-tp-dcs/
- https://www.twilio.com/docs/glossary/what-is-gsm-7-character-encoding
- https://twiliodeved.github.io/message-segment-calculator/
- GSM 03.38: Alphabets and language-specific information
- 3GPP TS 23.038 V6.1.0 (2004-09)