GSM 7 bit encode/decode - GSM 7 bit Default alphabet and default alphabet extension table

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/diangangqin/article/details/102525963

SMS(短信)对于ASCII可显示字符需要用GSM 7 bit进行PDU的编解码。GSM 7 bit由于只用7 个bit编码字符,这样可以多存储一些字符。例如对于短信,140个字节如果编码采用8bit,那可以存储140个,但是如果采用GSM 7 bit最大可以存储160个字符,多了20个字符,这样子有可能就会节约一条短信,也会降低通信设备的压力。
对于GSM 7 bit一直没有仔细学习和研究过,一方面认为GSM 7 bit可能就是对ASCII 编码的最高位(bit8)进行了简单的舍弃即可,另外参与的项目也有对字符进行GSM 7 bit的转换的库和函数,同时也认为这个可能比较简单,就是将字符转为一个7 bit的整数,或者将一个7 bit的数转换为一个字符,转换的过程依赖于字符和7 bit的对应表即可,可能比较麻烦的是由于是7 bit进行存储,需要进行移位操作,但是流程应该大体是这样的。最近有一些时间可以进行学习,就对这部分进行了探究,里面还是有很多东西值得学习的。下面提及的GSM 7 bit default table 和extension table 均来自:(3GPP TS 23.038 version 10.0.0 Release 10) 。

GSM 7 bit Default Alphabet character table:
在这里插入图片描述
GSM 7 bit default alphabet extension character table:
在这里插入图片描述

首先比对字符“1”,“a”,“A”在ASCII表和GSM 7 bit表中编码的差异。“1”的ASCII码值是0x31,“A”的是0x41,“a”的是0x61,在GSM 7 bit default table表中找到对应的字符发现“1”处在default table表中的第3列第1行(以0开始计算),“A”处在第4列第一行,“a”处在第6列第1行,又比对了其他的英文字符,发现这不是巧合,GSM 7 bit的值和ASCII码值是一样的(仅限于大小写字母和数字),并且字符在表中的位置就是字符的码值,default表就是一张字符和码值的对应表。
如何将ASCII字符编码成GSM 7 bit呢?是否可以直接将字符ASCII码的最高位bit8舍弃即可呢?这个想法行不通,比对一下ASCII码表中前面的值,发现ASCII码表和GSM 7 bit在对于非字母非数字的字符处理上,还是有比较大的差异的,并且没有对应关系。那是否还有其他方法呢?
仔细观察GSM 7 bit table表和发现,字符在7 bit 表中的位置就是字符的7 bit编码值。如果我们将GSM 7 bit 表中的字符按照列一个一个的拼起来,形成一个含有128个字符的字符串,那么每个字符在字串中的位置就是码值。例如“1”在字串中的位置正好是49(0x31),也就是其对应的码值。这样问题就解决了,如果给我们一个需要编码成7bit的字符串,那么就对需要编码的字符串中的字符一个一个的在GSM 7 bit字符形成的字符串中进行查找并数出所在的位置,并对字符所在的位置进行移位并拼接成新的码值数据。
GSM 7 bit除了default table,还有一张扩展表:default alphabet extension character table,增加了一些新的字符,同样是7 bit进行编码。那就奇怪了,同样都是7 bit进行编码,对于一个值,那么如何区分出是extension table表里的字符,还是default table里的字符呢?如果进行解码,那应该解成default table里的字符,还是extension table里的字符呢?这个处理还是很有意思和技术性的。在编码的过程中,如果发现字符不在default table里,而是在extension table里,那就先加入一个0x1B,之后继续添加字符在extension table里的位置就可以了。在解码的时候,如果发现0x1B,那就说明后面的字符在extension table里面。那如果想编码0x1B对应的字符怎么办呢?毕竟0x1B也是小于128的值,我们在两张table里面找到第一列和第11行(0开始计算),发现两张表里面0x1B对应的字符是一样的。如果想真的编码0x1B,那就认为这个值在extention table里,也就是编码的时候需要连续出现两个0x1B,不要认为0x1B在default table里,不然的话会解码错误。
这里只是简单解绍了一下GSM 7 bit table和extension table,对于natinal languable table(shift table和 locking shit table)的处理可以完全比对GSM 7 bit default table和extention table的处理。这里我更感慨的是GSM 7 bit default table的设计,对于我们熟悉的字母和字符和ASCII table一致,非常的巧妙。另外就是对于那些extension table表里的字符的编码处理和0x1B在default table和extension table设计成同一个字符,回味无穷。而这种设计有条件的,就是需要进行编码的字符很少在extension表里。如果很多,那使用GSM 7 bit编码就得不偿失了(14个bit编码一个extension table的字符)。
这里就不提供源码了,大家如果想参考一些实现,我比较推荐的是android上面的GsmAlphabet.java

Frameworks\base\telepony\java\com\android\internal\telephony\GsmAlphabet.java

中的函数
stringToGsm7BitPacked(这个是编码)
gsm7BitPackedToString(这个是解码)

这篇文章的逻辑就是来自这支文件。如果有说得不对的地方,请赐教,希望我们能一起进步。

猜你喜欢

转载自blog.csdn.net/diangangqin/article/details/102525963
BIT