Skip to main content
edited body
Source Link

I wrote a function doto decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here. I used the charset from here.

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with fewer shifts or & checks, but the thing I really don't like is my counter variable that I reset at 7. Any advice on how to improve this code?

I wrote a function do decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here. I used the charset from here.

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with fewer shifts or & checks, but the thing I really don't like is my counter variable that I reset at 7. Any advice on how to improve this code?

I wrote a function to decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here. I used the charset from here.

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with fewer shifts or & checks, but the thing I really don't like is my counter variable that I reset at 7. Any advice on how to improve this code?

added 8 characters in body; edited tags
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

I wrote a function do decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here. I used the charset from herehere.

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with fewer shifts or & checks, but the thing I really don't like is my counter variable that I reset at 7. Any advice on how to improve this code?

I wrote a function do decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here. I used the charset from here.

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with fewer shifts or & checks, but the thing I really don't like is my counter variable that I reset at 7. Any advice on how to improve this code?

I wrote a function do decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here. I used the charset from here.

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with fewer shifts or & checks, but the thing I really don't like is my counter variable that I reset at 7. Any advice on how to improve this code?

deleted 28 characters in body
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

I wrote a function do decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here.

  I used the charset from: github here.com/OpenSmpp/opensmpp (Can't post more than 2 links yet, sorry)

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with lessfewer shifts or && checks, but the thing I really don't like is my counter variable that I reset at 7... Any advice on how to improve this code?

I wrote a function do decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here.

  I used the charset from: github.com/OpenSmpp/opensmpp (Can't post more than 2 links yet, sorry)

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with less shifts or & checks, but the thing I really don't like is my counter variable that I reset at 7... Any advice on how to improve this code?

I wrote a function do decode GSM 7-Bit encoded messages as defined in the 3GPP standard. Example available here. I found a tool to help me check my answers here. I used the charset from here.

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");
    }
}

Tests:

@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("[email protected]");
}

I feel like I could have done this with fewer shifts or & checks, but the thing I really don't like is my counter variable that I reset at 7. Any advice on how to improve this code?

Source Link
Loading