什么样的Bit Twiddling Hack是这段代码?

时间:2014-09-02 18:58:15

标签: c# bit-manipulation

        int iHex = 0x42F4;
        int iResult = 0;
        Int16[] iLookupTable = new Int16[16];

        for (int i = 0; i < 16; i++)
        {
            iLookupTable[i] = (Int16)(iHex & 1);
            iHex >>= 1;
        }
        if (iLookupTable[0] == 1)
            iResult += 0x8;
        if (iLookupTable[1] == 1)
            iResult += 0x800;
        if (iLookupTable[2] == 1)
            iResult += 0x4;
        if (iLookupTable[3] == 1)
            iResult += 0x400;
        if (iLookupTable[4] == 1)
            iResult += 0x2;
        if (iLookupTable[5] == 1)
            iResult += 0x200;
        if (iLookupTable[6] == 1)
            iResult += 0x1;
        if (iLookupTable[7] == 1)
            iResult += 0x100;
        if (iLookupTable[8] == 1)
            iResult += 0x1000;
        if (iLookupTable[9] == 1)
            iResult += 0x10;
        if (iLookupTable[10] == 1)
            iResult += 0x2000;
        if (iLookupTable[11] == 1)
            iResult += 0x20;
        if (iLookupTable[12] == 1)
            iResult += 0x4000;
        if (iLookupTable[13] == 1)
            iResult += 0x40;
        if (iLookupTable[14] == 1)
            iResult += 0x8000;
        if (iLookupTable[15] == 1)
            iResult += 0x80;

        MessageBox.Show("0x" + iResult.ToString("X"));
        // Output: 0x8317

我已经反汇编并反编译了一个需要16位十六进制数字的旧程序,在做了一些比特杂乱无章的黑客之后它将16位结果输出到屏幕,上面的代码是它的作用,有人可以告诉我是什么类型的Bit Twiddling Hack是这个代码吗?

3 个答案:

答案 0 :(得分:2)

如果你像这样解决原始数字的位:

0123 4567 89AB CDEF

然后它会将它们重新排列为这个顺序:

1357 ECA8 0246 FDB9

首先是所有奇数位,然后是所有偶数位,第2位和第2位。按照第一和第二顺序相反的顺序进行第4次nybble第三个nybbles。

好的,现在让我们玩吧:

    int iHex = 0x42F4;
    int iResult = 0;
    UInt16[] bits = new UInt16[16] {0x8, 0x800, 0x4, 0x400, 0x2, 0x200, 0x1, 0x100,
                              0x1000, 0x10, 0x2000, 0x20, 0x4000, 0x40, 0x8000, 0x80};

    for (int i = 0; i < 16; i++)
    {
        if ((iHex & 1) == 1)
              iResult += bits[i];
        iHex >>= 1;
    }

    MessageBox.Show("0x" + iResult.ToString("X"));
    // Output: 0x8317

答案 1 :(得分:1)

如果您取原始的16位,并将它们从0到F编号:

"0123 4567 89AB CDEF"

重新排列的值按以下顺序包含这些位:

"6420 9BDF 7531 8ACE"

这不是一个我知道的默认操作,就像一个小端到大端编码,但肯定有一个模式。也许某些值被混淆,或者这是加密/散列函数的一部分。

答案 2 :(得分:0)

我认为这是代码所做的正确重新排列:

比特位置为:
0123 4567 89AB CDEF
要:
3B2A 1908 C4D5 E6F7

这就是解码器:

    private UInt16 Decode(UInt16 iHex)
    {
        UInt16[] bits = new UInt16[16] {0x40, 0x800, 0x4, 0x1, 0x200, 0x800, 0x2000, 0x8000,
              0x80, 0x20, 0x8, 0x2, 0x100, 0x400, 0x1000, 0x4000};

        for (int i = 0; iHex != 0; iHex >>= 1, i++)
        {
            if ((iHex & 1) == 1)
                iResult += bits[i];
        }
        return iResult;
    }