我编写了一个功能来解码GSM 7位编码的消息,如3 3GPP标准所定义的那样。示例可用的这里。我找到了一个工具来帮助我检查我的答案这里。我使用了来自这里的字符集。
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");
}
}测试:
@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重新设置它。对于如何改进这段代码,有什么建议吗?
发布于 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");抛出异常时,我建议在输入数据上添加一些上下文,从而导致错误消息。当
不要忘记测试错误的输入数据,例如
我还建议创建一个帮助类,并使用hamcrest匹配器来提高测试的可读性,即assertThat(hex("f4f29c9e769f1b"), is("testing"))
https://codereview.stackexchange.com/questions/155961
复制相似问题