...making Linux just a little more fun!
René Pfeiffer [lynx at luchs.at]
Hello, Gang!
I am trying to compute a SHA1 hash inside a C++ program without linking to additional libraries. There are some SHA1 code snippets around and they seem to work. So far so good. In order to compare SHA1 sums it's nice to have them in hexadecimal representation. The SHA1 code I used holds the sum in a byte array which is basically an array of unsigned chars. Creating hexadecimal output can be done as follows:
// Filename: hex_output.cc - cout test firing range #include <iomanip> #include <ios> #include <iostream> #include <stdlib.h> using namespace std; int main(int argc, char **argv) { unsigned char array[10]; unsigned short i; // An array with a French accent (sorry, SCNR) array[0] =3D 'A'; array[1] =3D 'L'; array[2] =3D 'L'; array[3] =3D 'o'; array[4] =3D ' '; array[5] =3D 'O'; array[6] =3D 'r'; array[7] =3D 'l'; array[8] =3D 'd'; array[9] =3D '!'; for( i=3D0; i<10; i++) { cout << hex << setfill('0') << setw(2) << nouppercase << array[i]; } cout << endl << endl; return(0); }
Unfortunately this outputs: 0A0L0L0o0 0O0r0l0d0!
As soon as I change the cout line to
cout << hex << setfill('0') << setw(2) << nouppercase << (unsigned short)array[i];
it works and produces: 414c4c6f204f726c6421
It's late and I still lack my good night coffee, but why is that? I didn't expect this behaviour.
Best, René.
Jimmy O'Regan [joregan at gmail.com]
2008/6/26 René Pfeiffer <lynx@luchs.at>:
> Hello, Gang! > > I am trying to compute a SHA1 hash inside a C++ program without linking > to additional libraries. There are some SHA1 code snippets around and > they seem to work. So far so good. In order to compare SHA1 sums it's > nice to have them in hexadecimal representation. The SHA1 code I used > holds the sum in a byte array which is basically an array of unsigned > chars. Creating hexadecimal output can be done as follows: > > // Filename: hex_output.cc - cout test firing range > > #include <iomanip> > #include <ios> > #include <iostream> > > #include <stdlib.h> > > using namespace std; > > int main(int argc, char **argv) { > unsigned char array[10]; > unsigned short i; > > // An array with a French accent (sorry, SCNR) > array[0] = 'A'; > array[1] = 'L'; > array[2] = 'L'; > array[3] = 'o'; > array[4] = ' '; > array[5] = 'O'; > array[6] = 'r'; > array[7] = 'l'; > array[8] = 'd'; > array[9] = '!'; > for( i=0; i<10; i++) { > cout << hex << setfill('0') << setw(2) << nouppercase << array[i]; > } > cout << endl << endl; > return(0); > } >
Break it down even more:
#include <ios> #include <iostream> using namespace std; int main () { cout << hex << 'a'; } Output: a
> Unfortunately this outputs: 0A0L0L0o0 0O0r0l0d0! > > As soon as I change the cout line to > > cout << hex << setfill('0') << setw(2) << nouppercase << (unsigned short)array[i]; > > it works and produces: 414c4c6f204f726c6421 > > It's late and I still lack my good night coffee, but why is that? I > didn't expect this behaviour. >
'hex' is only defined to take an integer; because it's a stream modifier, the only reasonable thing for it to do when it encounters input it can't process is to output it unmodified.
Jimmy O'Regan [joregan at gmail.com]
2008/6/26 Jimmy O'Regan <joregan@gmail.com>:
> 2008/6/26 René Pfeiffer <lynx@luchs.at>: >> It's late and I still lack my good night coffee, but why is that? I >> didn't expect this behaviour. >> > > 'hex' is only defined to take an integer; because it's a stream > modifier, the only reasonable thing for it to do when it encounters > input it can't process is to output it unmodified. >
#include <ios> #include <iostream> using namespace std; int main () { cout << hex << "maybe desirable: " << 32; } output: maybe desirable: 20
René Pfeiffer [lynx at luchs.at]
On Jun 26, 2008 at 0331 +0100, Jimmy O'Regan appeared and said:
> 2008/6/26 Jimmy O'Regan <joregan@gmail.com>: > > 2008/6/26 René Pfeiffer <lynx@luchs.at>: > >> It's late and I still lack my good night coffee, but why is that? I > >> didn't expect this behaviour. > > > > 'hex' is only defined to take an integer; because it's a stream > > modifier, the only reasonable thing for it to do when it encounters > > input it can't process is to output it unmodified. > > > > #include <ios> > #include <iostream> > > using namespace std; > > int main () > { > cout << hex << "maybe desirable: " << 32; > } > > output: maybe desirable: 20
Ok, I didn't think of that. Now it makes sense. The problem is that most examples I found turn a hex string into an integer and other examples just state "use hex" and use integer types.
Thanks, René.