如何在没有前缀掩码长度的情况下将HexString转换为带有符号或无符号的Int? [蟒蛇]

时间:2017-04-27 07:07:15

标签: python bit-manipulation bitwise-operators

问题:

如何在Python中将HexString转换为Int signed或unsigned而不带前缀掩码长度?

是的......已经存在关于此的主题。但是对于这个规范,答案是不充分或不完整的。 我只是想传递一个字符串 - 仅此而已 - 并获得它的等价物(有符号或无符号,任何大小)。

示例:

Passing FFFFFFFFFFFFFFFFF
Getting -1

Passing 9F1281F0
Getting -1626177040

Passing 1234
Getting 4660

1 个答案:

答案 0 :(得分:0)

几个小时后,我找到了一个解决方案。

它将每个十六进制数字视为一个4位整数,虽然这并非总是如此,但它也不是问题。

Ex:0x7是0b111。因此,Python中的整数将具有3位。检查:

a = 7
print( a.bit_length() )
#3

但如果最高位(信号位)没有第四位,则计算为0,这正是我们想要的情况。

所以,代码(未优化)但我能够呈现的最清晰的是:

HEX_BITS = 4

def shift_left1( bits ):
    #Left shift adding 1 instead of 0
    mask = 0
    for i in range( bits ):
        mask = (mask << 1) + 1
    return mask

def hex_signal( value, bits ):
    # Retuns the mask with bit signal
    signal_mask =  1 << bits
    return -( value & ( signal_mask ) )

def hex_without_signal( value, bits ):
    # Returns value with the number of bits given (from less significant to most)
    return value & shift_left1( bits )

def hex2dec( hstring, signed=True ):
    value = int( hstring, 16)
    if signed: #Do we want to check the signal?
        value_bits = len( hstring ) * HEX_BITS # A full hex digit have four bits
        shift_times = value_bits - 1 # Times to subfunctions shifts
        signal_mask = hex_signal( value, shift_times ) # Mask with bit value setted
        unsigned_hex_mask = hex_without_signal( value, shift_times ) # Value without most significant bit
        return signal_mask | unsigned_hex_mask # Or bit a bit from the unsigned value and signal mask
    else: # If not just returns the native conversion
        return value 

<强>示例:

print( hex2dec( "2" ) )
#2
print( hex2dec( "E" ) )
#-2
print( hex2dec( "4" ) )
#4
print( hex2dec( "FF" ) )
#-1
print( hex2dec( "0F" ) )
#15
print( hex2dec( "1F" ) )
#31
print( hex2dec( "1234" ) )
#4660
print( hex2dec( "9F1281F0" ) )
#-1626177040