1

我正在开发一个 android 短信网关项目,该项目从不同国家的客户端应用程序接收短信。在客户端应用程序中,我使用{, }, [and]来识别作为 SMS 发送到网关的消息的某些部分的开始和结束。如此链接中给出的,这些字符是被转义的特殊字符。有时网关收到的短信无法解码转义字符,会分别显示为_(, _), _<_>。这可以通过以下方式处理。

  1. 处理此问题的一种方法是更改​​客户端应用程序中的编码机制并仅使用默认字符集。
  2. 另一种方法是处理网关中的转义字符。

我不想采用选项 1,因为该解决方案不会向后兼容并且支持该产品可能会变得困难。

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

这个问题主要出现在跨国短信中。

非常感谢任何帮助。

4

1 回答 1

3

你有几个选择:

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

  2. 按照 GSM 规范,您可以进行以下解码:

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

例如:

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,
};

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

是来自 3GPP 的信息的根源,指定如何处理默认/扩展字符集。特别注意每个表下的注释!!

于 2011-12-23T08:17:42.067 回答