How to turn a hex string into an unsigned char array?

后端 未结 7 1268
春和景丽
春和景丽 2020-11-27 06:05

For example, I have a cstring \"E8 48 D8 FF FF 8B 0D\" (including spaces) which needs to be converted into the equivalent unsigned char array {0xE8,0x48,0

7条回答
  •  佛祖请我去吃肉
    2020-11-27 06:45

    The old C way, do it by hand ;-) (there is many shorter ways, but I'm not golfing, I'm going for run-time).

    enum { NBBYTES = 7 };
    char res[NBBYTES+1];
    const char * c = "E8 48 D8 FF FF 8B 0D";
    const char * p = c;
    int i = 0;
    
    for (i = 0; i < NBBYTES; i++){
        switch (*p){
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
          res[i] = *p - '0';
        break;
        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
          res[i] = *p - 'A' + 10;
        break;
       default:
         // parse error, throw exception
         ;
       }
       p++;
       switch (*p){
       case '0': case '1': case '2': case '3': case '4':
       case '5': case '6': case '7': case '8': case '9':
          res[i] = res[i]*16 + *p - '0';
       break;
       case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
          res[i] = res[i]*16 + *p - 'A' + 10;
       break;
       default:
          // parse error, throw exception
          ;
       }
       p++;
       if (*p == 0) { continue; }
       if (*p == ' ') { p++; continue; }
       // parse error, throw exception
    }
    
    // let's show the result, C style IO, just cout if you want C++
    for (i = 0 ; i < 7; i++){
       printf("%2.2x ", 0xFF & res[i]);
    }
    printf("\n");
    

    Now another one that allow for any number of digit between numbers, any number of spaces to separate them, including leading or trailing spaces (Ben's specs):

    #include 
    #include 
    
    int main(){
        enum { NBBYTES = 7 };
        char res[NBBYTES];
        const char * c = "E8 48 D8 FF FF 8B 0D";
        const char * p = c;
        int i = -1;
    
        res[i] = 0;
        char ch = ' ';
        while (ch && i < NBBYTES){
           switch (ch){
           case '0': case '1': case '2': case '3': case '4':
           case '5': case '6': case '7': case '8': case '9':
              ch -= '0' + 10 - 'A';
           case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
              ch -= 'A' - 10;
              res[i] = res[i]*16 + ch;
              break;
           case ' ':
             if (*p != ' ') {
                 if (i == NBBYTES-1){
                     printf("parse error, throw exception\n");
                     exit(-1);
                }
                res[++i] = 0;
             }
             break;
           case 0:
             break;
           default:
             printf("parse error, throw exception\n");
             exit(-1);
           }
           ch = *(p++);
        }
        if (i != NBBYTES-1){
            printf("parse error, throw exception\n");
            exit(-1);
        }
    
       for (i = 0 ; i < 7; i++){
          printf("%2.2x ", 0xFF & res[i]);
       }
       printf("\n");
    }
    

    No, it's not really obfuscated... but well, it looks like it is.

提交回复
热议问题