使用python将十六进制字符串转换为整数 [英] Convert hex-string to integer with python

查看:1251
本文介绍了使用python将十六进制字符串转换为整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意,问题不是十六进制转换为十进制,而是一串十六进制值转换为整数.

Note that the problem is not hex to decimal but a string of hex values to integer.

说我从一个十六进制转储中得到了一个字符串(例如'6c 02 00 00'),所以我需要先将其转换为实际的十六进制,然后再获取它表示的整数...(这个特殊的数字是620作为int16和int32)

Say I've got a sting from a hexdump (eg. '6c 02 00 00') so i need to convert that into actual hex first, and then get the integer it represents... (this particular one would be 620 as an int16 and int32)

我尝试了很多事情,但自己却更加困惑.有没有一种快速的方法可以在python(最好是3.x)中进行这种转换?

I tried a lot of things but confused myself more. Is there a quick way to do such a conversion in python (preferably 3.x)?

推荐答案

不仅是字符串,而且按小端顺序排列-意思是只删除空格并使用int(xx, 16)调用即可.它的实际字节值也不是4个任意的0-255数字(在这种情况下struct.unpack将起作用).

Not only that is a string, but it is in little endian order - meanng that just removing the spaces, and using int(xx, 16) call will work. Neither does it have the actual byte values as 4 arbitrary 0-255 numbers (in which case struct.unpack would work).

我认为一种不错的方法是将组件交换回人类可读"的顺序,并使用int调用-因此:

I think a nice approach is to swap the components back into "human readable" order, and use the int call - thus:

number = int("".join("6c 02 00 00".split()[::-1]), 16)

那里发生了什么:Expession的第一部分是split-它在空格处断开字符串,并提供一个包含四个字符串的列表,每个字符串两个数字.接下来是[::-1]特殊切片-大致意味着向我提供前一个序列的元素子集,从边缘开始,一次返回1个元素"-这是一种常见的Python惯用法任何顺序.

What happens there: the first part of th expession is the split - it breaks the string at the spaces, and provides a list with four strings, two digits in each. The [::-1] special slice goes next - it means roughly "provide me a subset of elements from the former sequence, starting at the edges, and going back 1 element at a time" - which is a common Python idiom to reverse any sequence.

此反向序列用于对"".join(...)的调用-该调用基本上将空字符串用作该序列上每个元素的连接器-此调用的结果为"0000026c".有了这个值,我们就可以调用Python的int类,该类接受一个辅助的可选参数,该参数表示应该用于解释第一个参数表示的数字的基数.

This reversed sequence is used in the call to "".join(...) - which basically uses the empty string as a concatenator to every element on the sequence - the result of the this call is "0000026c". With this value, we just call Python's int class which accepts a secondary optional paramter denoting the base that should be used to interpret the number denoted in the first argument.

>>> int("".join("6c 02 00 00".split()[::-1]), 16)
620

另一种选择是累计添加每个2位数字的转换,并根据其位置适当地调整其权重-尽管通过4行Python for循环,也可以使用reduce在单个表达式中完成此操作更具可读性:

Another option, is to cummulatively add the conversion of each 2 digits, properly shifted to their weight according to their position - this can also be done in a single expression using reduce, though a 4 line Python for loop would be more readable:

>>> from functools import reduce #not needed in Python2.x
>>> reduce(lambda x, y: x  + (int(y[1], 16)<<(8 * y[0]) ), enumerate("6c 02 00 00".split()), 0)
620

更新 OP只是说他实际上没有在字符串中包含空格"-在这种情况下,可以使用相同的方法使用abotu,但是用两位数代替split()致电:

update The OP just said he does not actually have the "spaces" in the string - in that case, one can use just abotu the same methods, but taking each two digits instead of the split() call:

reduce(lambda x, y: x  + (int(y[1], 16)<<(8 * y[0]//2) ), ((i, a[i:i+2]) for i in range(0, len(a), 2)) , 0)

(其中a是带有数字的变量)- 或者,将其转换为内存中的实际4字节数字,使用十六进制编解码器,然后使用struct解压缩该数字-这对于您的代码而言可能更符合语义:

(where a is the variable with your digits, of course) - Or, convert it to an actual 4 byte number in memory, usign the hex codec, and unpack the number with struct - this may be more semantic correct for your code:

import codecs
import struct
struct.unpack("<I", codecs.decode("6c020000", "hex") )[0]

因此,这里的方法是将每个2位数字传递给codecs.decode调用返回的字节对象中的内存中的实际字节,并构造为将缓冲区中的4个字节读取为单个32位整数.

So the approach here is to pass each 2 digits to an actual byte in memory in a bytes object returned by the codecs.decode call, and struct to read the 4 bytes in the buffer as a single 32bit integer.

这篇关于使用python将十六进制字符串转换为整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆