微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

标志的按位运算?

如何解决标志的按位运算?

我见过一些使用按位运算来创建选项/标志的代码

例如,请考虑 ssl library 中的以下示例:

# bitwise AND and NOT
ctx = ssl.create_default_context(Purpose.CLIENT_AUTH)
ctx.options &= ~ssl.OP_NO_SSLv3

# bitwise OR
client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
client_context.options |= ssl.OP_NO_TLSv1
client_context.options |= ssl.OP_NO_TLSv1_1

这些标志的数值:

>>> ssl.OP_NO_SSLv3.value
33554432
>>> ssl.OP_NO_TLSv1.value
67108864
>>> ssl.OP_NO_TLSv1_1.value
268435456

我不明白这种创建标志的系统是如何工作的,或者这些数字是如何选择的。我研究过操作符是如何工作的,但我仍然很困惑。

有人可以解释一下这是如何工作的,以及适当的用例吗?

解决方法

当你看二进制时,这些数字似乎不那么随机:)

>>> "{:032b}".format(ssl.OP_NO_SSLv3.value)
'00000010000000000000000000000000'

>>> "{:032b}".format(ssl.OP_NO_TLSv1.value)
'00000100000000000000000000000000'

>>> "{:032b}".format(ssl.OP_NO_TLSv1_1.value)
'00010000000000000000000000000000'

>>> client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
... client_context.options |= ssl.OP_NO_TLSv1
... client_context.options |= ssl.OP_NO_TLSv1_1
>>> "{:032b}".format(client_context.options)
'10010110010100100000000001010100'

每个选项只是一个可以设置或清除的位。

,

除非您在头脑中自动将十进制转换为二进制,否则打印标志簇的十进制值是很愚蠢的。根据您的喜好以二进制、八进制或十六进制打印。

典型的用例是当你有

  • 一组相关的布尔值。
  • 密集的二进制字段序列,例如机器代码操作。

将这些视为布尔值的打包记录。例如,您可能需要跟踪对象权限(读写修改销毁)。您可以将其作为四个单独的布尔值来执行,或者简单地创建一个值来对所有四个进行编码。例如,只有读取和销毁权限 R--D 的人的权限值为 1001 或 0x9。

当您想要检查特定权限时,您可以使用按位运算来屏蔽您不想要的权限。例如:

r_mask = b'1000
w_mask = b'0100
m_mask = b'0010
d_mask = b'0001

现在,检查很简单。要查看某人是否对某个对象具有读取权限:

if obj.permission & d_mask:
    # Allow operation

为了改变值,你可以允许操作赋予写入或修改权限:

if obj.permission & (w_mask | m_mask):

或者如果您是记住访问代码的强硬派:

if obj.permission & b'0110':

当您处理小字段(例如机器代码或通信协议)的打包记录时,从传输字中提取一个字段会很有用。 例如,如果您需要从指令中获取操作码,您可以屏蔽除(例如)5 个操作码位之外的所有操作码位并将它们移到单词的右边缘:

op_mask = 0x7c00                         # bits 30-26 hold the op code
opcode = (instruction & op_mask) >> 26   # Shift right 26 bits

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。