-5

I have a typical use case where i need to convert the unsigned char values to hexadecimal.

For example,

unsigned char *pBuffer = (unsigned char *)pvaluefromClient //where pvaluefromclient is received from a client

The length of pBuffer is 32 bytes and it holds the value as follows,

(gdb) p pBuffer 
$5 = (unsigned char *) 0x7fd4b82cead0 "EBA5F7304554DCC3702E06182AB1D487"
(gdb) n

STEP 1: I need to split this pBuffer value as follows,

{EB,A5,F7,30,45,54,DC,C3,70,2E,06,18,2A,B1,D4,87 }

STEP 2: I need to convert the above splited values to decimal as follows,

const unsigned char pConvertedBuffer[16] = {
    235,165,247,48,69,84,220,195,112,46,6,24,42,177,212,135
};

Any idea on how to achieve the STEP1 and STEP2? any help on this would be highly appreciated

Mario Super
  • 309
  • 3
  • 14

3 Answers3

1

How about something like this:

unsigned char *pBuffer = (unsigned char *)pvaluefromClient //where valuefromclient is received from a client

int i, j;
unsigned char target[16]
for(i=0;i<32;i+=2)
{
   sscanf((char*)&pBuffer[i], "%02X", &j);
   target[i/2] = j;
}
Illishar
  • 886
  • 1
  • 11
  • 24
  • I think this is the simplest solution, if wrapped properly in a function. `C` functions are usually good, "performant" and simple solutions, provided you have properly sanitized the input – KABoissonneault Jun 10 '16 at 12:27
  • @lllishar, The solution looks fine to me. But I am trying to convert this in c++. Do you have any idea on "sscanf" equivalent part in c++? – Mario Super Jun 13 '16 at 09:43
  • unless you mean "how to combine this with iostream" it shouldn't be a problem to use it as is. C++ can use ansi c functions just as well. Just include the stdio. – Illishar Jun 13 '16 at 13:52
0

You can create a function that takes two unsigned chars as parameter and returns another unsigned char. The two parameters are the chars (E and B for the first byte). The returned value would be the numerical value of the byte.

The logic would be :

unsigned char hex2byte(unsigned char uchar1, unsigned char uchar2) {
    unsigned char returnValue = 0;

    if((uchar1 >= '0') && (uchar1 <= '9')) {
        returnValue = uchar1 - 0x30; //0x30 = '0'
    }
    else if((uchar1 >= 'a') && (uchar1 <= 'f')) {
        returnValue = uchar1 - 0x61 + 0x0A; //0x61 = 'a'
    }
    else if((uchar1 >= 'A') && (uchar1 <= 'F')) {
        returnValue = uchar1 - 0x41 + 0x0A; //0x41 = 'A'
    }

    if((uchar2 >= '0') && (uchar2 <= '9')) {
        returnValue = (returnValue <<8) + (uchar2 - 0x30); //0x30 = '0'
    }
    else if((uchar2 >= 'a') && (uchar2 <= 'f')) {
        returnValue = (returnValue <<8) + (uchar2 - 0x61 + 0x0A); //0x61 = 'a'
    }
    else if((uchar2 >= 'A') && (uchar1 <= 'F')) {
        returnValue = (returnValue <<8) + (uchar2 - 0x41 + 0x0A); //0x41 = 'A'
    }        

    return returnValue;
}

The basic idea is to calculate the numerical value of the chars and to reassemble a number from two chars (hence the bit shift)

I'm pretty sure there are multiple more elegant solutions than mine here and there.

Tim
  • 1,853
  • 2
  • 24
  • 36
0
void Conversion(char *pBuffer, int *ConvertedBuffer)
{
    int j = 0;
    for(int i = 0; i < 32; i += 2)
    {
        std::stringstream ss;
        char sz[4] = {0};

        sz[0] = pBuffer[i];
        sz[1] = pBuffer[i+1];
        sz[2] = 0;

        ss << std::hex << sz;
        ss >> ConvertedBuffer[j];
        ++j;
    }
}
int  main()
{
    char Buffer[] = "EBA5F7304554DCC3702E06182AB1D487";
    int ConvertedBuffer[16];
    Conversion(Buffer, ConvertedBuffer);
    for(int i = 0; i < 16; ++i)
    {
        cout << ConvertedBuffer[i] << " ";
    }
    return 0;
}

//output:
235 165 247 48 69 84 220 195 112 46 6 24 42 177 212 135
sameerkn
  • 2,209
  • 1
  • 12
  • 13