如何将这五个字节还原为四个字节?
将输入的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'
问题是 - 如何从给定的10位十六进制数回到8位十六进制数(例如:08 86 42 98 E8 转换为 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
附注:我认为这个问题不仅限于8位或10位。如果输入是11
,那么输出将是08
。
1 个回答
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^1
其实就是2^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^某个数
来乘,可以看作是向左移动的操作。
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^某个数
是用来和16为底的数相乘的。这样,这4个字节的数字
AAAABBBB CCCCDDDD EEEEFFFF GGGGHHHH
就变成了5个字节的这个:
0AAAA0BB BB0CCCC0 DDDD0EEE E0FFFF0G GGG0HHHH
所以,利用这个图示,你可以创建一个函数,它接受10位的十六进制数字,并通过简单的位运算输出成4位的十六进制数字。
为了简单起见,我会在这个示例C代码中使用无符号字符:
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
}
输出结果(请查看完整代码):
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