【问题标题】:Convert ASCII String to 7-bit GSM coding scheme将 ASCII 字符串转换为 7 位 GSM 编码方案
【发布时间】:2018-04-20 14:43:35
【问题描述】:

我编写的一个简单的例程,用于将ASCII 字符串转换为对应的7-bit GSM 编码方案:

#include <stdio.h>
#include <process.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>

/* convert ascii input string to 7-bit GSM alphabet */
bool ascii_to_gsm(const char* in, uint8_t len, uint8_t* out, uint8_t start_indx) {
    if (in == NULL || out == NULL || len == 0)
        return false;

    uint8_t nshift = 7;
    memcpy(out + start_indx, in, len);
    for (size_t i = 0; i < len - 1; i++) {
        nshift = (nshift == 255) ? 7 : nshift;
        uint16_t l = out[start_indx + i];
        uint16_t h = out[start_indx + i + 1];
        h = (h << nshift--) | l;
        out[start_indx + i] = h;
        out[start_indx + i + 1] = h >> 8;
    }

    return true;
}

int main() {
    char data[] = "ASCIIASCII";
    uint8_t buff[sizeof(data) - 1];
    memset(buff, 0, sizeof(buff));
    ascii_to_gsm(data, sizeof(buff), buff, 0);
    for (size_t i = 0; i < sizeof(buff); i++) {
        printf("\n buff[%d]=%02x", i, buff[i]);
    }
    system("pause");

    return 0;
}

对于像ASCIITEST 这样的字符串,它工作正常,输出分别为C1E9309904D4E2940A

但是对于字符串ASCIIASCII,一些输出字节是错误的: C1E930990C4E87498024

结果应该是:C1E930990C4E87C924

不知道是哪一部分,我错了。

关于GSM编码的概念可以在here找到。

我使用this在线编码器比较结果

【问题讨论】:

  • 为什么这段代码不起作用对于 SO 来说是题外话。
  • 嗯,输出的“字节”长度在C1E930990C4E87498024C1E930990C4E87C924之间是不同的。
  • 看起来您的代码为每一个字节的输入生成一个字节的输出。 (实际上,它似乎为每个输入字节生成 两个 字节的输出,但它似乎覆盖了其中的一半,您可能想要查看。)但是如果 GSM 是 7 位编码,我猜您希望平均为每个输入字节生成 7/8 个字节,或者为每 8 个输入字节生成 7 个字节的输出。 “ASCIIASCII”是10个字节长,你生成10个字节的输出,正确答案是9个字节的输出。
  • @SteveSummit。是的,这非常正确,GSM 编码中最大 140 字节的 SMS 可能是 160 个字符长度。

标签: c encoding ascii gsm pdu


【解决方案1】:

但是对于字符串 ASCII ASCII 一些输出字节是错误的:
C1E930990C4E87498024
结果应该是:
C1E930990C4E87C924

OP 的代码没有考虑到输出的长度可能比输入的长度短。

如果输入是 10 个 ASCII 字符,即 70 位。输出需要是上限(70/8)或 9 个字节。另见@Steve Summit


缺少start_indx 的简化参考代码。由于输入是一个字符串(“转换ASCII字符串”),所以不需要输入长度。

bool ascii_to_gsmA(const char* in, uint8_t* out) {
  unsigned bit_count = 0;
  unsigned bit_queue = 0;
  while (*in) {
    bit_queue |= (*in & 0x7Fu) << bit_count;
    bit_count += 7;
    if (bit_count >= 8) {
      *out++ = (uint8_t) bit_queue;
      bit_count -= 8;
      bit_queue >>= 8;
    }
    in++;
  }
  if (bit_count > 0) {
    *out++ = (uint8_t) bit_queue;
    }
  return true;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多