brnby
brnby

Reputation: 1523

printf: Displaying an SHA1 hash in hexadecimal

I have been following the msdn example that shows how to hash data using the Windows CryptoAPI. The example can be found here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa382380%28v=vs.85%29.aspx

I have modified the code to use the SHA1 algorithm.

I don't understand how the code that displays the hash (shown below) in hexadecmial works, more specifically I don't understand what the >> 4 operator and the & 0xf operator do.

if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)){
    printf("MD5 hash of file %s is: ", filename);
    for (DWORD i = 0; i < cbHash; i++)
    {
        printf("%c%c", rgbDigits[rgbHash[i] >> 4],
           rgbDigits[rgbHash[i] & 0xf]);
    }
    printf("\n");
}

I would be grateful if someone could explain this for me, thanks in advance :)

Upvotes: 2

Views: 893

Answers (2)

Piotr Tkaczyk
Piotr Tkaczyk

Reputation: 152

this code uses simple bit 'filtering' techniques

  • ">> 4" means shift right by 4 places, which in turn means 'divide by 16'
  • "& 0xf" equals to bit AND operation which means 'take first 4 bits'

Both these values are passed to rgbDigits which proly produced output in valid range - human readable

Upvotes: 2

Jerry Coffin
Jerry Coffin

Reputation: 490118

x >> 4 shifts x right four bits. x & 0xf does a bitwise and between x and 0xf. 0xf has its four least significant bits set, and all the other bits clear.

Assuming rgbHash is an array of unsigned char, this means the first expression retains only the four most significant bits and the second expression the four least significant bits of the (presumably) 8-bit input.

Four bits is exactly what will fit in one hexadecimal digit, so each of those is used to look up a hexadecimal digit in an array which presumably looks something like this:

char rgbDigits[] = "0123456789abcdef"; // or possibly upper-case letters

Upvotes: 3

Related Questions