代码之家  ›  专栏  ›  技术社区  ›  IMAN4K

将ASCII字符串转换为7位GSM编码方案

  •  2
  • IMAN4K  · 技术社区  · 6 年前

    我为转换而编写的一个简单例程 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;
    }
    

    对于字符串,如 ASCII码 TEST 它工作正常,输出 C1E9309904 D4E2940A 分别地

    但对于字符串 ASCIIASCII 某些输出字节错误: C1E930990C4E87498024

    结果应该是: C1E930990C4E87C924

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

    可以找到有关GSM编码的概念 here

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

    1 回复  |  直到 6 年前
        1
  •  2
  •   chux    6 年前

    但对于字符串ASCIIASCII,某些输出字节错误:
    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;
    }
    
    推荐文章