GSM 03.38编码方案中的转义码

时间:2011-12-22 16:32:20

标签: android encoding escaping gsm sms-gateway

我正在开发一个android sms网关项目,它接收来自不同国家/地区的客户端应用程序的短信。在客户端应用程序中,我使用{, }, []来标识作为SMS发送到网关的消息的某些部分的开头和结尾。如this链接中所示,这些字符是转义的特殊字符。有时,网关收到的短信无法解码转义字符,它将分别显示为_(, _), _<_>。这可以通过以下方式处理。

  1. 处理此问题的一种方法是更改​​客户端应用程序中的编码机制,并仅使用默认字符集。
  2. 其他方法是处理网关中的转义字符。
  3. 我不想采用选项1,因为解决方案不会向后兼容,支持产品可能会变得困难。

    我想采取选项2,但我不确定我究竟能做到这一点。特别是,我不确定可以使用哪些不同的转义字符(_是其中之一)以及如何检测转义码。

    这个问题主要出现在越野短信中。

    非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

您有几个选择:

  1. 使用Android短信解码系统(相对较好,不完美但足够好)

  2. 遵循GSM规范,您可以进行以下解码:

    在解码每个字符时,您必须验证字符是否是“默认字符集”的一部分,或者它是否是“扩展字符集”的转义。转义字符为 0x1B ,这告诉解码器,然后下一个字符必须来自“扩展字符集”。如果您的解码器没有找到该字符在“扩展字符集”中,那么通过GSM规范,它必须首先尝试在“默认字符集”中找到该字符。如果它也不在“默认字符集”中,则必须使用空格字符

  3. 例如:

    if (escaped) {
      char ext = (char) GSMUtils.BYTE_TO_CHAR_ESCAPED[val];
      // if no character defined then do fall back
      ext = ext != -1 ? ext : (char) GSMUtils.BYTE_TO_CHAR[val];
      // if no character defined then fall back to <space> 
      return ext != -1 ? ext : ' '; 
    } else {
      char ch = (char) GSMUtils.BYTE_TO_CHAR[val];
      // if no character defined then fall back to <space>
      return ch != -1 ? ch : ' '; 
    }
    

    其中GSMUtils.BYTE_TO_CHAR_ESCAPED和GSMUtils.BYTE_TO_CHAR是int []的

    private static final int[] BYTE_TO_CHAR = {
        0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC,
        0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5,
        0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8,
        0x03A3, 0x0398, 0x039E, 0x00A0, 0x00C6, 0x00E6, 0x00DF, 0x00C9,
        0x0020, 0x0021, 0x0022, 0x0023, 0x00A4, 0x0025, 0x0026, 0x0027,
        0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
        0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
        0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
        0x00A1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
        0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
        0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
        0x0058, 0x0059, 0x005A, 0x00C4, 0x00D6, 0x00D1, 0x00DC, 0x00A7,
        0x00BF, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
        0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
        0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
        0x0078, 0x0079, 0x007A, 0x00E4, 0x00F6, 0x00F1, 0x00FC, 0x00E0,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
            -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
    };
    

    private static final int[] BYTE_TO_CHAR_ESCAPED = {
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1, 0x000C,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1, 0x005E,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
    0x007B, 0x007D,     -1,     -1,     -1,     -1,     -1, 0x005C,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1, 0x005B, 0x007E, 0x005D,     -1,
    0x007C,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     0x20AC, -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
    };
    

    我可能会补充说,解码问题不一定只是一个跨国问题。由于扩展字符集中有许多字符经常用于国家短信中。

    Here是来自3GPP的信息的根源,指定如何处理默认/扩展字符集。特别注意每张桌子下面的笔记!!