如何将这个简单的5个字节转换回4个字节? (将4个字节转换为5个字节的算法是已知的)

时间:2011-01-16 11:18:38

标签: python algorithm math

将输入的8位十六进制数转换为10位的算法如下:

Given that the 8 digit number is: '12 34 56 78'

x1 = 1 * 16^8 * 2^3
x2 = 2 * 16^7 * 2^2
x3 = 3 * 16^6 * 2^1
x4 = 4 * 16^4 * 2^4
x5 = 5 * 16^3 * 2^3
x6 = 6 * 16^2 * 2^2
x7 = 7 * 16^1 * 2^1
x8 = 8 * 16^0 * 2^0

Final 10 digit hex is:
=> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 
=> '08 86 42 98 E8'

问题是 - how to go back to 8 digit hex from a given 10 digit hex (for example: 08 86 42 98 E8 to 12 34 56 78)

以下是一些示例输入和输出:

input                output

11 11 11 11          08 42 10 84 21
22 22 33 33          10 84 21 8C 63
AB CD 12 34          52 D8 D0 88 64
45 78 96 32          21 4E 84 98 62
FF FF FF FF          7B DE F7 BD EF

P.S。我认为问题不仅限于8位或10位数。如果输入为11,则输出为08。  

1 个答案:

答案 0 :(得分:5)

从此转换算法:

x1 = 1 * 16^8 * 2^3
x2 = 2 * 16^7 * 2^2
x3 = 3 * 16^6 * 2^1
x4 = 4 * 16^4 * 2^4
x5 = 5 * 16^3 * 2^3
x6 = 6 * 16^2 * 2^2
x7 = 7 * 16^1 * 2^1
x8 = 8 * 16^0 * 2^0

您可以看到16^4之后它跳到16^6。 拉一下,以便安排得很好。

x1 = 1 * 16^7 * 16^1 * 2^3
x2 = 2 * 16^6 * 16^1 * 2^2
x3 = 3 * 16^5 * 16^1 * 2^1
x4 = 4 * 16^4 * 2^4
x5 = 5 * 16^3 * 2^3
x6 = 6 * 16^2 * 2^2
x7 = 7 * 16^1 * 2^1
x8 = 8 * 16^0 * 2^0

16^12^4,所以

x1 = 1 * 16^7 * 2^4 * 2^3
x2 = 2 * 16^6 * 2^4 * 2^2
x3 = 3 * 16^5 * 2^4 * 2^1
x4 = 4 * 16^4 * 2^4
x5 = 5 * 16^3 * 2^3
x6 = 6 * 16^2 * 2^2
x7 = 7 * 16^1 * 2^1
x8 = 8 * 16^0 * 2^0

将它们放在一起,你会看到电源很好地上升。

x1 = 1 * 16^7 * 2^7
x2 = 2 * 16^6 * 2^6
x3 = 3 * 16^5 * 2^5
x4 = 4 * 16^4 * 2^4
x5 = 5 * 16^3 * 2^3
x6 = 6 * 16^2 * 2^2
x7 = 7 * 16^1 * 2^1
x8 = 8 * 16^0 * 2^0

2^something相乘可以看作是左移算子。

x1 = 1 * 16^7 << 7
x2 = 2 * 16^6 << 6
x3 = 3 * 16^5 << 5
x4 = 4 * 16^4 << 4
x5 = 5 * 16^3 << 3
x6 = 6 * 16^2 << 2
x7 = 7 * 16^1 << 1
x8 = 8 * 16^0 << 0

16^something用于乘以16。这样,这4个字节的数字

AAAABBBB CCCCDDDD EEEEFFFF GGGGHHHH

成为5个字节:

0AAAA0BB BB0CCCC0 DDDD0EEE E0FFFF0G GGG0HHHH

因此,使用该图片,您可以使用简单的按位操作创建一个采用10位十六进制数并输出为4位十六进制数的函数。

为简单起见,我将在此示例C代码中使用unsigned char:

void convert(unsigned char five[], unsigned char four[]) {
    four[0] = (five[0] << 1) & 0xF0  // 11110000
            | (five[0] << 2) & 0x0C  // 00001100
            | (five[1] >> 6) & 0x03; // 00000011
    four[1] = (five[1] << 3) & 0xF0  // 11110000
            | (five[2] >> 4) & 0x0F; // 00001111
    four[2] = (five[2] << 5) & 0xE0  // 11100000
            | (five[3] >> 3) & 0x10  // 00010000
            | (five[3] >> 2) & 0x0F; // 00001111
    four[3] = (five[3] << 7) & 0x80  // 10000000
            | (five[4] >> 1) & 0x70  // 01110000
            | (five[4])      & 0x0F; // 00001111
}

输出(见full code):

 08 42 10 84 21      11 11 11 11
 10 84 21 8C 63      22 22 33 33
 52 D8 D0 88 64      AB CD 12 34
 21 4E 84 98 62      45 78 96 32
 7B DE F7 BD EF      FF FF FF FF