Java преобразует 7-битные октеты Charset в читаемую строку (из PDU SMS)
Я получаю SMS от GSM модема в формате PDU; TP-User-Data - это "C8329BFD06DDDF72363904"
и что я получаю: "is2 r69", в то время как отправленное смс - "Hello World!".
Вот мой код Java:
private String fromPDUText(String PDUSMSText) {
String endoding = PDUSMSText.substring(0, 2);
PDUSMSText = PDUSMSText.substring(18);
byte bs[] = new byte[PDUSMSText.length() / 2];
for(int i = 0; i < PDUSMSText.length(); i += 2) {
bs[i / 2] = (byte) Integer.parseInt(PDUSMSText.substring(i, i + 2), 16);
}
try {
String out = new String(bs, "ASCII");
} catch(UnsupportedEncodingException e) {
e.printStackTrace();
return "";
} finally {
return out;
}
}
3 ответа
Входные данные упакованы в 7 бит на символ, что означает, что каждые 8 байтов кодируют 9 символов. Создание парсера для этого формата может быть забавным упражнением или разочаровывающим опытом, в зависимости от того, как вы его принимаете. Возможно, вам лучше использовать библиотеку, и быстрый поиск в Google показывает несколько примеров кода.
Вот как упакованы 7-битные символы:
Кодирование-декодирование-7-разрядное-User-Data-для-SMS-PDU-PDU
Лично я считаю, что проще всего атаковать такого рода проблему, рассматривая ее как канал, в котором вы подаете 8 бит на одном конце и извлекаете 7 бит на другом. Пока в канале есть как минимум 7 битов, которые вы читаете из него. Когда есть менее 7 бит, вам нужно добавить еще несколько, чтобы вы записали в него 8 новых бит. Итак, что вам нужно, это:
- Канал, который может содержать по крайней мере 14 бит (но почему быть дешевым? Идите с 32-битным int!).
- Счетчик отслеживания количества битов в канале в любой данный момент.
Алгоритм в псевдокоде выглядит следующим образом:
pipe = 0;
bitCount = 0;
while(hasMoreData())
{
pipe |= readByte() << bitCount;
bitCount += 8;
while(bitCount >= 7)
{
writeByte(pipe & 0x7F);
pipe >>= 7;
bitCount -= 7;
}
}