Peter
Peter

Reputation: 16943

bitwise operators - get single hex number (0-15) at certain position

Let's say we have hex number

x = 0x345ABC678

how can I get single hex digit (0-15) for given position >>using bitwise operators only<< ?

for example I want to get 4th number (0xA) or 6th (0xC) from hex number.


To make a long story short, I want to brute-force loop thru big database of words I converted them to 64-bit numbers (instead of strings) for example word "PUZZLER" is a number 29996611546. A is 1, Z is 33. So I want to get third letter (stored as decimal 1-33) from int 29996611546. If you could explain to me how to deal with hexadecimals I can use it in my script.

I am simple PHP programmer so I haven't had to use bitwise operators in long long time, I hope you can help me.

Upvotes: 1

Views: 494

Answers (2)

tdao
tdao

Reputation: 17668

Steve Summit's solution/explanation is clear.

Alternatively, a 64bit number can be split into 16 hexa digits using variable bit mask. Then leading zeros can be omitted to display the meaningful digits only.

#include <iostream>

int main()
{
    using namespace std;

    typedef unsigned long long u64;
    u64 number = 0x345ABC678;
    int digits[16] = {0};
    for( int i = 0; i < 16; i++ )    // fill in all 16 digits, incl. possible leading zero.
    {
        int shift_bits =  64 - 4 * ( i + 1 );
        u64 mask = 0xFULL << shift_bits;
        digits[i] = ( number & mask ) >> shift_bits;
    }

    int j = 0;
    while( !digits[j] ){ j++; }     // find the first index with non-zero digit.

    cout << hex << uppercase;
    cout << "digit #4 = " << hex << digits[ j + 3 ] << endl;
    cout << "digit #6 = " << hex << digits[ j + 5 ] << endl;
}

Outcome:

digit #4 = A
digit #6 = C

Upvotes: 2

Steve Summit
Steve Summit

Reputation: 47962

You could start with something like

(x >> ((8 - i) * 4)) & 0xf

This numbers the digits from left to right, 1-8.

To explain how it works: Consider the example 0x45ABC678. Suppose we want the 3rd digit. We want to shift the number to the right using the >> operator, then pick off the last digit. In this case, we want to shift it to the right by 5 hex digits (which is 5*4 = 20 bits), throwing away the BC678 and leaving 0x45A. Then, when we pick off the last digit using a bitwise AND with 0xf, we get the last digit 0xA.

To get the first digit we have to shift by 7 digits. To get the third digit we have to shift by 5 digits. To get the 8th digit we have to shift by 0 digits. 8 - i gives us that pattern.

Upvotes: 1

Related Questions