按位运算符 - 在特定位置获取单个十六进制数 (0-15)

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

假设我们有十六进制数

x = 0x345ABC678

如何获得给定位置的单个十六进制数字 (0-15) >> 仅使用按位运算符<< ?

例如我想从十六进制数中得到第 4 个数字 (0xA) 或第 6 个数字 (0xC)。


长话短说,我想通过大型单词数据库进行强力循环,我将它们转换为 64 位数字(而不是字符串),例如单词 "PUZZLER" 是一个数字 29996611546。 A 是 1,Z 是 33。所以我想从 int 29996611546 中获取第三个字母(存储为十进制 1-33)。如果你能向我解释如何处理十六进制,我可以在我的脚本中使用它。

我是一个简单的PHP程序员,所以我已经很久没有使用按位运算符了,希望你能帮助我。

你可以从

这样的东西开始
(x >> ((8 - i) * 4)) & 0xf

这对数字从左到右编号,1-8。

解释它是如何工作的:考虑示例 0x45ABC678。假设我们想要第三位数字。我们想使用 >> 运算符将数字右移,然后取下最后一位。在这种情况下,我们想将它向右移动 5 个十六进制数字(即 5*4 = 20 位),丢掉 BC678 并留下 0x45A。然后,当我们使用 0xf 按位与选择最后一个数字时,我们得到最后一个数字 0xA.

要获得第一位数字,我们必须移动 7 位数字。要获得第三位数字,我们必须移动 5 位数字。要获得第 8 位数字,我们必须移动 0 位数字。 8 - i 给了我们那个模式。

Steve Summit 的 solution/explanation 很清楚。

或者,可以使用可变位掩码将 64 位数字拆分为 16 个十六进制数字。然后可以省略前导零以仅显示有意义的数字。

#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;
}

结果:

digit #4 = A
digit #6 = C