在C ++中优化十六进制到Ascii函数

时间:2013-02-15 20:34:21

标签: c++ function hex ascii

这是c ++中的一个函数,它接受一个HEX字符串并将其转换为等效的ASCII字符。

string HEX2STR (string str)
{
    string tmp;
    const char *c = str.c_str();
    unsigned int x;
    while(*c != 0) {
        sscanf(c, "%2X", &x);
        tmp += x;
        c += 2;
    }
    return tmp;

如果输入以下字符串:

537461636b6f766572666c6f77206973207468652062657374212121

输出将是:

Stackoverflow is the best!!!

假设我要在此函数中输入1,000,000个唯一的HEX字符串,计算需要一段时间。

有没有更有效的方法来完成这个?

5 个答案:

答案 0 :(得分:5)

当然。一次查找两个字符:

unsigned char val(char c)
{
    if ('0' <= c && c <= '9') { return c      - '0'; }
    if ('a' <= c && c <= 'f') { return c + 10 - 'a'; }
    if ('A' <= c && c <= 'F') { return c + 10 - 'A'; }
    throw "Eeek";
}

std::string decode(std::string const & s)
{
    if (s.size() % 2) != 0) { throw "Eeek"; }

    std::string result;
    result.reserve(s.size() / 2);

    for (std::size_t i = 0; i < s.size() / 2; ++i)
    {
        unsigned char n = val(s[2 * i]) * 16 + val(s[2 * i + 1]);
        result += n;
    }

    return result;
}

答案 1 :(得分:2)

就在我编写它之前,这应该是相当有效的:)

const char lookup[32] =
     {0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0};

std::string HEX2STR(std::string str)
{
  std::string out;
  out.reserve(str.size()/2);

  const char* tmp = str.c_str();

  unsigned char ch, last = 1;
  while(*tmp)
  {
    ch <<= 4;
    ch |= lookup[*tmp&0x1f];
    if(last ^= 1) 
      out += ch;
    tmp++;
  }
  return out;
}

答案 2 :(得分:0)

不要使用sscanf。这是一个非常通用的灵活功能,这意味着它允许所有这些用例的速度很慢。相反,走一下字符串并自己转换每个角色的速度要快得多。

答案 3 :(得分:0)

此例程采用带有(我称之为)六角形的字符串,通常用于嵌入式ECU,例如“31 01 7F 33 38 33 37 30 35 31 30 30 20 20 49”,并尽可能以可读ASCII格式对其进行转换。 通过处理ASCII表中的不连续性进行转换(0-9:48-57,A-F:65-70);

    int i,j, len=strlen(stringWithHexWords);
    char ascii_buffer[250];
    char c1, c2, r;

    i=0;
    j=0;

    while (i<len) {

        c1 = stringWithHexWords[i];
        c2 = stringWithHexWords[i+1];

        if ((int)c1!=32) {  // if space found, skip next section and bump index only once                                       
        // skip scary ASCII codes                                       
           if (32<(int)c1 && 127>(int)c1 && 32<(int)c2 && 127>(int)c2)  { 
//

           // transform by taking first hexdigit * 16 and add second hexdigit
           // both with correct offset


            r = (char) ((16*(int)c1+((int)c2<64?((int)c2-48):((int)c2-55)))); 


            if (31<(int)r && 127>(int)r) 
                      ascii_buffer[j++] = r;   // check result for readability      
           }
          i++;  // bump index 
     }   

    i++;  // bump index once more for next hexdigit
}

ascii_bufferCurrentLength = j;
return true;

}

答案 4 :(得分:0)

hexToString()函数将十六进制字符串转换为ASCII可读字符串

string hexToString(string str){
    std::stringstream HexString;
    for(int i=0;i<str.length();i++){
        char a = str.at(i++);
        char b = str.at(i);
        int x = hexCharToInt(a);
        int y = hexCharToInt(b);
        HexString << (char)((16*x)+y);
    }
    return HexString.str();
}

int hexCharToInt(char a){
    if(a>='0' && a<='9')
        return(a-48);
    else if(a>='A' && a<='Z')
        return(a-55);
    else
        return(a-87);
}