python - python:检查字节对象中前导零的有效方法
问题描述
我正在寻找一种有效的方法来检查字节对象中的前导零。检查也应该针对半食进行。现在我只用search_zeros
函数检查字节;其中输入参数是::n
要检查的前导零的数量,以及inp_bytes
字节对象:
def search_zeros(inp_bytes, n): # inp_bytes is always 20 bytes
if n % 2 ==0:
bytes_to_check = n // 2
check_bytes = bytes(bytes_to_check)
else:
# check for nibbles?
return
if inp_bytes[:bytes_to_check] == check_bytes:
return inp_bytes
print(search_zeros(b'\x00\x002\xe04\x83\xb1.)\x1c\x17\xa5\xb7u\xcc\n\xb0\xfdg0', 2))
>>>b'\x00\x002\xe04\x83\xb1.)\x1c\x17\xa5\xb7u\xcc\n\xb0\xfdg0'
# How to check for nibbles?
print(search_zeros(b'\x00\xe04\xe04\x83\xb1.)\x1c\x17\xa5\xb7u\xcc\n\xb0\xfdg0', 1))
>>> None
我正在阅读有关按位运算的内容,并且正在尝试熟悉该主题。这可以在这里适用吗?
编辑
我知道我可以使用.startswith(b'\x00')
,但有更快的方法吗?
澄清:
inp_bytes
如果函数以恰好零个半字节开始,则该函数应该返回n
,不多不少,否则它应该返回None
。
解决方案
我会避免构造check_bytes
,因为当 n 非常大时,这会消耗内存中不必要的存储空间。所以我的方法是使用循环或等效的理解。
其他注意事项:
- 如果字符串太短,我假设您不希望出现异常,因此我为这种情况添加了一些逻辑。我认为
len(inp_bytes)
是一个恒定的时间操作,所以这应该很快。 - 我使用的事实是一个字节
y
在非零时为“真”,我很确定这是一种最快的方式,但基准测试可以确认,如果你真的在所有可以节省的纳秒之后。 n
如果是奇数,您可以使用按位运算来测试最后一个半字节。请注意,在 Python 中,按位运算是在字节上定义的,而不是在字节序列中定义的。b'\xf0'
是一个字节序列,因此会& b'\xf0'
产生异常。b'\xf0'[0]
是该序列中的第一个(也是唯一一个)字节,它被接受为&
.- 编辑:您在评论中澄清了您只希望
inp_bytes
在前导零的数量完全等于n
--logic 时返回以检查下一个半字节是否非零。
考虑到所有这些,这是我的解决方案:
def search_zeros(inp_bytes, n):
if len(inp_bytes) < (n+1)//2:
return None
if any(y for y in inp_bytes[:n//2]):
return None
if n % 2 != 0 and inp_bytes[n//2] & b'\xf0'[0] != 0:
return None
# Make sure the next nibble is not zero:
if n % 2 != 0:
if inp_bytes[n//2] & b'\x0f'[0] != 0:
return inp_bytes
else:
if len(inp_bytes) == n//2 or inp_bytes[n//2] & b'\xf0'[0] != 0:
return inp_bytes
return None
x=b'\x00\x00\x03\x44'
for n in range(10):
print(f"n={n} x={x} result={search_zeros(x, n)}")
x=b'\x00'
for n in range(5):
print(f"n={n} x={x} result={search_zeros(x, n)}")
x=b'\x00\x10'
for n in range(5):
print(f"n={n} x={x} result={search_zeros(x, n)}")
x=b'\x00\x01'
for n in range(5):
print(f"n={n} x={x} result={search_zeros(x, n)}")
输出:
n=0 x=b'\x00\x00\x03D' result=None
n=1 x=b'\x00\x00\x03D' result=None
n=2 x=b'\x00\x00\x03D' result=None
n=3 x=b'\x00\x00\x03D' result=None
n=4 x=b'\x00\x00\x03D' result=None
n=5 x=b'\x00\x00\x03D' result=b'\x00\x00\x03D'
n=6 x=b'\x00\x00\x03D' result=None
n=7 x=b'\x00\x00\x03D' result=None
n=8 x=b'\x00\x00\x03D' result=None
n=9 x=b'\x00\x00\x03D' result=None
n=0 x=b'\x00' result=None
n=1 x=b'\x00' result=None
n=2 x=b'\x00' result=b'\x00'
n=3 x=b'\x00' result=None
n=4 x=b'\x00' result=None
n=0 x=b'\x00\x10' result=None
n=1 x=b'\x00\x10' result=None
n=2 x=b'\x00\x10' result=b'\x00\x10'
n=3 x=b'\x00\x10' result=None
n=4 x=b'\x00\x10' result=None
n=0 x=b'\x00\x01' result=None
n=1 x=b'\x00\x01' result=None
n=2 x=b'\x00\x01' result=None
n=3 x=b'\x00\x01' result=b'\x00\x01'
n=4 x=b'\x00\x01' result=None
推荐阅读
- azure - 如何在 Azure Active Directory 中使用凭据进行身份验证?
- union - 在 RDS Aurora 上失败的两个大表的联合
- spring - java.lang.NoClassDefFoundError: org.springframework.web.util.ExpressionEvaluationUtils
- mysql - AWS RDS 低可用内存和正在使用的交换
- java - 在 onBindViewHolder (RecyclerView Adapter) 中创建动态意图
- javascript - 给定这些示例,我想要给定一组唯一数据
- java - 如何从 CSV 文件聚合数据以存储到 Java 中的对象链表中
- react-native - 从 React Native 访问 iOS 配置文件?
- java - Spring Data JPA orphanRemoval 不起作用
- javascript - iphone图像在webapp和safari中加载缓慢