首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Java解析GSM 7位消息

用Java解析GSM 7位消息
EN

Code Review用户
提问于 2017-02-21 20:16:26
回答 1查看 2.2K关注 0票数 4

我编写了一个功能来解码GSM 7位编码的消息,如3 3GPP标准所定义的那样。示例可用的这里。我找到了一个工具来帮助我检查我的答案这里。我使用了来自这里的字符集。

代码语言:javascript
复制
public String decode(final byte[] data) {
    if (data == null) {
        return null;
    }

    final ByteArrayOutputStream bos = new ByteArrayOutputStream();
    for (int i = 0, counter = 0; i < data.length; i++, counter++) {
        final byte current = data[i];
        final byte previous = i == 0 ? 0 : data[i - 1];

        if (counter == 7) {
            counter = 0;
        }

        final int shiftedCurrent = (current << counter) & 0x7F;
        final int shiftedPrevious = (previous & 0xFF) >> (8 - counter);
        bos.write(shiftedCurrent | shiftedPrevious);

        if (counter == 6) {
            bos.write((current & 0xFF) >> 1);
        }
    }

    try {
        final String result = bos.toString("X-Gsm7Bit");
        return result.endsWith("\r") ? result.substring(0, result.length() - 1) : result;
    } catch (final UnsupportedEncodingException e) {
        throw new AsnDecodeException("Cannot get charset: X-Gsm7Bit");
    }
}

测试:

代码语言:javascript
复制
@Test
public void decodeTests() throws DecoderException {
    assertThat(decode(Hex.decodeHex("f4f29c9e769f1b".toCharArray()))).isEqualTo("testing");
    assertThat(decode(Hex.decodeHex("31D98C56B3DD70".toCharArray()))).isEqualTo("12345678");
    assertThat(decode(Hex.decodeHex("6176D94DAFCB1B".toCharArray()))).isEqualTo("alentur");
    assertThat(decode(Hex.decodeHex("61F79B8E2ECB5B657CB80D679701E77638CD768DDF6D".toCharArray()))).isEqualTo("another-example@gmail.com");
}

我觉得我可以用更少的轮班或&检查来完成这个任务,但是我真正不喜欢的是我的计数器变量,我在7重新设置它。对于如何改进这段代码,有什么建议吗?

EN

回答 1

Code Review用户

发布于 2017-02-22 02:37:46

我真正不喜欢的是我的计数器变量,我把它重置为7。

可能只是继续以counter = (counter + 1) % 8的形式递增计数器,而不是将其保存在for循环中。

对于如何改进这段代码有什么建议吗?

这可能只是我一个人,但是位操作非常神秘,所以我想为0x7F & 0xFF提供一个变量来理解什么是特殊的

而且,我也不太清楚为什么counter == 6会导致额外的比特。如果你能把它转换成一个被调用的函数,那会很有帮助。

result.endsWith("\r")看起来有点奇怪。这是一个特殊的要求。如果是这样的话,您还需要处理\n吗?

throw new AsnDecodeException("Cannot get charset: X-Gsm7Bit");抛出异常时,我建议在输入数据上添加一些上下文,从而导致错误消息。当

不要忘记测试错误的输入数据,例如

  • "“
  • "zz“
  • “123456789”

我还建议创建一个帮助类,并使用hamcrest匹配器来提高测试的可读性,即assertThat(hex("f4f29c9e769f1b"), is("testing"))

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/155961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档