4 votes

Convertir de Hex String a Unsigned Char Array en C++

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

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

Output:

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 don't 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?

5voto

Trauma Points 17600

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 pair of bytes to a single hexadecimal value is fairly straightforward:

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

We use an auxiliary function to obtain the value of the crude of each ASCII character; if it is >= 'A' the numerical value is char - 55 , y char - 48 otherwise.

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

I leave it up to you to support lowercase letters; you only have to modify the function slightly. fromASCII( ) .

2 votes

Pure C++, but from year 98 ;P

0 votes

@Paula_plus_plus Some of us are still following anchored in the past what can we do :-)

4voto

PaperBirdMaster Points 24910

If you can compile in C++17, you can take advantage of the function 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;
}

0 votes

What if I can't compile in C++17?

0 votes

If you can't compile in C++17, you can use a std::stringstream or the Trauma solution

HolaDevs.com

HolaDevs is an online community of programmers and software lovers.
You can check other people responses or create a new question if you don't find a solution

Powered by:

X