0

我需要通过两个不同的十六进制字符串传输大于 65535 的值,以便在接收到字符串时,可以将它们连接起来再次形成整数。例如,如果值为 70000,则两个字符串将是 0x0001 和 0x1170。

我认为这就像将整数转换为十六进制一样简单,然后将其右移 4 以获得顶部字符串并删除除最后 4 个字符之外的所有字符。

我想我可能正在为一些语法(对 Python 来说相当新)和一些逻辑而苦苦挣扎。谁能想到一个简单的方法来做到这一点?

谢谢

4

5 回答 5

3

使用divmod内置函数:

>>> [hex(x) for x in divmod(70000, 65536)]
['0x1', '0x1170']
于 2012-06-20T17:02:12.540 回答
1

你的意思是这样吗?

In [1]: big = 12345678
In [2]: first, second = hex(big)[2:][:-4], hex(big)[2:][-4:]
In [3]: first, second
Out[3]: ('bc', '614e')

In [4]: int(first+second, 16)
Out[4]: 12345678
于 2012-06-20T16:59:06.520 回答
1

您的算法可以很容易地实现,如 Lev Levitsky 的回答:

hex(big)[2:-4], hex(big)[-4:]

但是,对于 65536 以下的数字,它将失败。

你可以解决这个问题,但你最好拆分数字,然后将两半转换为十六进制,而不是拆分十六进制字符串。

ecatmur 的回答可能是最简单的方法:

[hex(x) for x in divmod(70000, 65536)]

或者您可以将您的“右移/截断”算法翻译成这样的数字:

hex(x >> 16), hex(x & 0xFFFF)

如果您需要这些字符串是“0x0006”而不是“0x6”,而不是在零件上调用十六进制,您可以这样做:

['%#06x' % (x,) for x in divmod(x, 65536)]

或者,使用更现代的字符串格式样式:

['0x{:04x}'.format(x) for x in divmod(x, 65536)]

但另一方面,您可能再次希望通过先转换为整数然后移动和屏蔽数字来撤消此操作,而不是连接字符串。与 ecatmur 的答案相反的是:

int(bighalf) * 65536 + int(smallhalf)

移位/掩码实现的(等效)逆是:

(int(bighalf) << 16) | int(smallhalf)

在这种情况下,您不需要左侧的额外 0。

还值得指出的是,如果数字可以为负数或大于 4294967295,这些算法都不会起作用,但这只是因为在这些情况下问题是不可能的。

于 2012-06-20T17:13:07.083 回答
0

对于大于65536或具有长度的数字>=5,您可以使用slicing

>>> num=70000
>>> var1=hex(num)[:-4]
>>> var2='0x'+hex(num)[-4:]
>>> integ=int(var1+var2[2:],16)
>>> print(integ)
    70000
于 2012-06-20T16:58:34.023 回答
0

警惕大/小端,你可以做的保持简单是:

val = 70000
to_send = '{:08X}'.format(val) # '00011170'
decoded = int('00011170', 16) # 70000

编辑:那么要非常清楚......

hex1, hex2 = to_send[:4], to_send[4:] # send these two and on receipt
my_number = int(hex1 + hex2, 16)
于 2012-06-20T17:21:13.693 回答