tags:

views:

53

answers:

3

Would I would like to be able to do is convert a char array (may be binary data) to a list of HEX values of the form: ab 0d 12 f4 etc....

I tried doing this with

lHexStream << "<" << std::hex << std::setw (2) << character << ">";

but this did not work since I would get the data printing out as:

<ffe1><2f><ffb5><54>< 6><1b><27><46><ffd9><75><34><1b><ffaa><ffa2><2f><ff90><23><72><61><ff93><ffd9><60><2d><22><57>

Note here that some of the values would have 4 HEX values in them? e.g.

What I would be looking for is what they have in wireshark, where they represent a char aray (or binary data) in a HEX format like:

08 0a 12 0f

where each character value is represented by just 2 HEX characters of the form shown above.

A: 

I think the problem is that the binary data is being interpreted as a multi-byte encoding when you're reading the characters. This is evidenced byt he fact that each of the 4-character hex codes in your example have the high bit set in the lower byte.

You probably want to read the binary stream in ascii mode.

Andrew Cooper
I doubt it, because the high byte is always 0xFF rather than some random number, as one would expect if it's doing some flaily conversion to UCS-2.
Zack
+3  A: 

It looks like byte values greater than 0x80 are being sign-extended to short (I don't know why it's stopping at short, but that's not important right now). Try this:

IHexStream << '<' << std::hex << std::setw(2) << std::setfill('0')
           << static_cast<unsigned int>(static_cast<unsigned char>(character))
           << '>';

You may be able to remove the outer cast but I wouldn't rely on it.

EDIT: added std::setfill call, which you need to get <06> instead of < 6>. Hat tip to jkerian; I hardly ever use iostreams myself. This would be so much shorter with fprintf:

fprintf(ihexfp, "<%02x>", (unsigned char)character);
Zack
+2  A: 

As Zack mentions, The 4-byte values are because it is interpreting all values over 128 as negative (the base type is signed char), then that 'negative value' is extended as the value is expanded to a signed short.

Personally, I found the following to work fairly well:

char *myString = inputString;
for(int i=0; i< length; i++)
    std::cout << std::hex << std::setw(2) << std::setfill('0') 
              << static_cast<unsigned int>(myString[i]) << " ";
jkerian