十六进制字符串转两个18位整数
Hexadecimal string to two 18-bit integer
我是十六进制的新手,找不到任何类似的以前的帖子。例如,我有一个十六进制字符串 50f116bcf
、b3b4d25d0
,已知它是一个 36 位整数。不确定它是已签名还是未签名。我想知道如何将十六进制到 38 位整数转换为 python 中的两个 18 位整数。
我在这个 post 中看到关于使用
将十六进制转换为 16 位有符号整数
def twos_complement(hexstr,bits):
value = int(hexstr,16)
if value & (1 << (bits-1)):
value -= 1 << bits
return value
twos_complement('FFFE',16)
-2
这也会推广到 38 位整数吗twos_complement('b3b4d25d0',38)
?
为了拆分整数,我看到 this post 使用
将一个 16 位整数(x
变量)拆分为两个 8 位
c = (x >> 8) & 0xff
f = x & 0xff
(1030333333 >> 8) & 0xff
163
(1030333333 >> 8)
4024739
这也可以推广到使用以下方法将一个已知的 38 位整数拆分为两个 16 位整数吗?
c = (x >> 16) & 0xff
f = x & 0xff
假设十六进制字符串表示一个正整数,您只需将最后两行修改为
>>> value = 0x50f116bcf
>>> msb = (value >> 18) & (2**18 - 1)
>>> lsb = value & (2**18 - 1)
# and convert (msb, lsb) back into value by using the binary OR
>>> (msb << 18) | lsb == value
True
或者概括这个想法并使用下面的函数
def bin_grouper(value, bits):
"""bin_grouper(0b1011010, 3) --> 001 011 010"""
import math
num = math.ceil(value.bit_length() / bits) # number of blocks
mask = 2**bits - 1
blocks = [(value >> idx*bits) & mask for idx in range(num)]
fmtstr = f'{{:0{bits}b}}'
return [fmtstr.format(v) for v in reversed(blocks)]
按顺序将一个 36 位数字拆分为两个 18 位数字:
>>> bin_grouper(0x50f116bcf, 18)
['010100001111000100', '010110101111001111']
# or
>>> bin_grouper(int('50f116bcf', 16), 18)
['010100001111000100', '010110101111001111']
为了比较结果,您可以将0x50f116bcf
转换成36位二进制字符串并测试高18位(msb)和低18位(lsb):
>>> bstr = f'{0x50f116bcf:036b}'
>>> bstr
'010100001111000100010110101111001111'
>>> blocks = bin_grouper(0x50f116bcf, 18)
>>> blocks[0] == bstr[:18] == f'{msb:018b}'
True
>>> blocks[1] == bstr[18:] == f'{lsb:018b}'
True
这是一个基础转换器:
def getbasetasifintisbaset(orig,basefrom=10, baseto=16):
num=orig
result = 0
i=0
while num != 0:
result += (num % basefrom) * (baseto ** i)
num //=basefrom
i += 1
return result
getbasetasifintisbaset(100,10,16)
#256
getbasetasifintisbaset(256,16,10)
#100
我是十六进制的新手,找不到任何类似的以前的帖子。例如,我有一个十六进制字符串 50f116bcf
、b3b4d25d0
,已知它是一个 36 位整数。不确定它是已签名还是未签名。我想知道如何将十六进制到 38 位整数转换为 python 中的两个 18 位整数。
我在这个 post 中看到关于使用
将十六进制转换为 16 位有符号整数def twos_complement(hexstr,bits):
value = int(hexstr,16)
if value & (1 << (bits-1)):
value -= 1 << bits
return value
twos_complement('FFFE',16)
-2
这也会推广到 38 位整数吗twos_complement('b3b4d25d0',38)
?
为了拆分整数,我看到 this post 使用
将一个 16 位整数(x
变量)拆分为两个 8 位
c = (x >> 8) & 0xff
f = x & 0xff
(1030333333 >> 8) & 0xff
163
(1030333333 >> 8)
4024739
这也可以推广到使用以下方法将一个已知的 38 位整数拆分为两个 16 位整数吗?
c = (x >> 16) & 0xff
f = x & 0xff
假设十六进制字符串表示一个正整数,您只需将最后两行修改为
>>> value = 0x50f116bcf
>>> msb = (value >> 18) & (2**18 - 1)
>>> lsb = value & (2**18 - 1)
# and convert (msb, lsb) back into value by using the binary OR
>>> (msb << 18) | lsb == value
True
或者概括这个想法并使用下面的函数
def bin_grouper(value, bits):
"""bin_grouper(0b1011010, 3) --> 001 011 010"""
import math
num = math.ceil(value.bit_length() / bits) # number of blocks
mask = 2**bits - 1
blocks = [(value >> idx*bits) & mask for idx in range(num)]
fmtstr = f'{{:0{bits}b}}'
return [fmtstr.format(v) for v in reversed(blocks)]
按顺序将一个 36 位数字拆分为两个 18 位数字:
>>> bin_grouper(0x50f116bcf, 18)
['010100001111000100', '010110101111001111']
# or
>>> bin_grouper(int('50f116bcf', 16), 18)
['010100001111000100', '010110101111001111']
为了比较结果,您可以将0x50f116bcf
转换成36位二进制字符串并测试高18位(msb)和低18位(lsb):
>>> bstr = f'{0x50f116bcf:036b}'
>>> bstr
'010100001111000100010110101111001111'
>>> blocks = bin_grouper(0x50f116bcf, 18)
>>> blocks[0] == bstr[:18] == f'{msb:018b}'
True
>>> blocks[1] == bstr[18:] == f'{lsb:018b}'
True
这是一个基础转换器:
def getbasetasifintisbaset(orig,basefrom=10, baseto=16):
num=orig
result = 0
i=0
while num != 0:
result += (num % basefrom) * (baseto ** i)
num //=basefrom
i += 1
return result
getbasetasifintisbaset(100,10,16)
#256
getbasetasifintisbaset(256,16,10)
#100