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

标签 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'

问题是 - 如何从给定的 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

最佳答案

从这个转换算法:

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

关于python - 如何将这个简单的 5 个字节变回 4 个字节? (将 4 个字节转换为 5 个字节的算法是已知的),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4704989/

相关文章:

java - 我如何针对 CyclicShift 优化此 Java 代码(Hackerearth 问题)?

c - X 与范围 L 到 R 中的每个数组元素的 XOR 的总和

javascript - 曲线公式(javascript 中的代数)

c# - 需要数学库来操作序列/范围

python - 用指数有效地计算数学公式

Python FTP下载-忽略下载目录中已存在的文件

Python any(iterable) 和 all(iterable) 没有短路和副作用

javascript - 如何使用 python 更改 html 行代码

c++ - 为什么我必须始终明确指定 STL 算法函数中的范围,即使我想在整个容器上工作?

algorithm - 比较两个数字 "likeness"