Convert from Hex String to Unsigned Char Array in C ++

4

I need to convert a string of string characters to an unsigned char array in this way:

string hex_str_texto = "0A4F1B3D5EEF354A";
unsigned char uchar_texto[80];

Exit:

uchar_texto[0] = 0x0A //Primeros dos elementos del string 
uchar_texto[1] = 0x4F
uchar_texto[2] = 0x1B

This works well sometimes but sometimes it does not work (I do not know why):

char *c_key1 = new char[80 + 1];

for(unsigned i = 0, unsigned_char_val; i < hex_str_texto.length(); i += 2)
{
    sscanf(hex_str_texto.c_str() + i, "%2X", &unsigned_char_val);
    c_key1[i/2] = unsigned_char_val;
    uchar_texto[i/2] = c_key1[i/2];
}

delete c_key1;

I tried this other way but it does not work (the fix is always zero):

sscanf(hex_str_texto.c_str(), "%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX...",
        &uchar_texto[0], &uchar_texto[1], &uchar_texto[2]...);

Is there another way to solve this?

    
asked by Noe Cano 12.09.2018 в 19:32
source

2 answers

4

If you can compile in C ++ 17, you can take advantage of the std::from_chars :

/* Pasado a formacion de char por comodidad para su proceso
   podrías usar string::data en su lugar. */
const char hex_str_texto[]{"FABADACAFEDEADF00D"};

int main()
{
    /* Al añadir las llaves {} al final, todos los elementos
       se inicializan a 0 */
    unsigned char uchar_texto[80]{};

    for (int b = 0, e = sizeof(hex_str_texto) - 1; b != e; b += 2)
    {
        std::from_chars(hex_str_texto + b, hex_str_texto + b + 2, uchar_texto[b / 2], 16);
    }

    return 0;
}

If your compiler does not support C ++ 17, you can use a std::stringstream :

const std::string hex_str_texto{"FABADACAFEDEADF00D"};

int main()
{
    /* Al añadir las llaves {} al final, todos los elementos
       se inicializan a 0 */
    unsigned char uchar_texto[80]{};

    for (int b = 0, e = hex_str_texto.length(); b != e; b += 2)
    {
        std::stringstream ss;
        ss << std::hex << hex_str_texto.substr(b, 2);

        int valor;
        ss >> valor;

        uchar_texto[b / 2] = valor;
    }

    return 0;
}
    
answered by 12.09.2018 / 22:20
source
5

A possible solution, using C ++ pure :

#include <vector>
#include <string>
#include <iostream>

static char fromASCII( const char c ) {
  return ( c < 'A' ) ? ( c - 48 ) : ( c - 55 );
}

int main( ) {
  std::string hex( "0A4F1B3D5EEF354A" );
  std::vector< unsigned char > result;

  const char *ptr = hex.c_str( );

  while( *ptr ) {
    char sub = fromASCII( *ptr ) * 15;
    ++ptr;
    sub += fromASCII( *ptr );

    ++ptr;

    result.push_back( sub );
  }

  for( auto idx : result ) std::cout << (int)idx << ' ';

  std::cout << '\n';

  return 0;
}

As you can see, the conversion of a couple of bytes to a single hexadecimal value is quite simple:

resultado = ( par[0] * 15 ) + par[1];

We use an auxiliary function to get the raw value of each ASCII character; if it is > = 'A' , the numeric value is char - 55 , and char - 48 otherwise.

Keep in mind that we do not check for errors; for example, if you use lowercase letters, the result will be curious ; -)

I leave to your enjoyment the support of lower case letters; you only have to modify the fromASCII( ) function slightly.

    
answered by 12.09.2018 в 20:29