python中将16进制数字字符串转化为10进制数值类型再比较大小
- 问题背景
- 错误原因
- 解决办法
- 第一种:使用系统自带的转化函数
- 第二种:使用我的自定义函数
- 性能升级版
- 普通数值字符串转化数值类型
问题背景
在工作中,看到一个上线的python代码竟然隐藏了代码,大家来感受下这段代码:(为避免泄露商业信息我做了去除隐私处理)
if str1 > '0x6001' and str1 < 'ffff' and str1 != '12a3':
print("succs")
else:
print("fail")
我们将str1赋一个值进行一下测试,来看看这惊为天人的代码效果如何。
来上图,公开处刑:
我输入的是一个0xfg01的字符串值,按理说是不会报错的
这竟然是一个已经上线了的代码,开发和测试都干嘛去了。。。。。惊呆了。
这是做开发以来我智商受到最大的侮辱。没有之一!!!
错误原因
python虽然是很动态类型的语言,很好用,但是它还没智能到这个程度,一切字符串都是按照字典顺序进行比较的。更不会知道你这个是个16进制的字符要自动转换后给你进行比较。
解决办法
第一种:使用系统自带的转化函数
反正我是没有找到,笑哭了,哈哈哈
第二种:使用我的自定义函数
优点:没有缺点
def hexStr2Number(strParam):
# strParam是一个16进制的字符串,应该仅包含数字0-9和字母ABCDEF。开头可以是0x。
# 如果不符合16进制的格式要求,我们将会返回 return False
if strParam == '' or strParam is None:
return False
if strParam[0] == '0' and strParam[1] == 'x':
strParam = strParam[2:]
strParam = strParam.upper()
len_of_hex = strParam.__len__()
dic_of_hex = {
"0":0,
"1":1,
"2":2,
"3":3,
"4":4,
"5":5,
"6":6,
"7":7,
"8":8,
"9":9,
"A":10,
"B":11,
"C":12,
"D":13,
"E":14,
"F":15
}
result = 0
for elem_of_strParam in strParam:
if elem_of_strParam in dic_of_hex:
result = result + dic_of_hex[elem_of_strParam]*(16**(len_of_hex-1))
len_of_hex -= 1
else:
return False
return result
方便的测试数据:
print(hexStr2Number("0xffff"))
print(hexStr2Number("ffff"))
print(hexStr2Number("0x11"))
print(hexStr2Number("0x23ff"))
print(hexStr2Number("0xasss"))
print(hexStr2Number(""))
测试结果:
65535
65535
17
9215
False
False
代码整改:
str1 = '0x7606'
if hexStr2Number(str1) > hexStr2Number('0x6001') and hexStr2Number(str1) < hexStr2Number('ffff') and hexStr2Number(str1) != hexStr2Number('12a3'):
print("succs")
else:
print("fail")
整改结果:
性能升级版
我们将幂运算改为了位运算,提升公共函数的性能,让你项目运行效率更高。
def hexStr2Number(strParam):
# strParam是一个16进制的字符串,应该仅包含数字0-9和字母ABCDEF。开头可以是0x。
# 如果不符合16进制的格式要求,我们将会返回 return False
if strParam == '' or strParam is None:
return False
if strParam[0] == '0' and strParam[1] == 'x':
strParam = strParam[2:]
strParam = strParam.upper()
len_of_hex = strParam.__len__()
dic_of_hex = {
"0":0,
"1":1,
"2":2,
"3":3,
"4":4,
"5":5,
"6":6,
"7":7,
"8":8,
"9":9,
"A":10,
"B":11,
"C":12,
"D":13,
"E":14,
"F":15
}
result = 0
for elem_of_strParam in strParam:
if elem_of_strParam in dic_of_hex:
#幂运算改为位运算,计算效率更高
result = result + (dic_of_hex[elem_of_strParam]<<(4*(len_of_hex-1)))
len_of_hex -= 1
else:
return False
return result
普通数值字符串转化数值类型