实际上,每个选项都是许多可能选项中的一个标志,因此您需要使用按位与 (&) 和按位或 (|) 运算来组合它们。这样做是因为这些选项不会相互排斥,您需要通过选择组合在一起的各种选项来构成最终值。所以每一个都有一个 2 的幂的值,这意味着它在某个特定位置有点为 1,然后最终值会编码每个特定的单独标志是打开还是关闭。
所以你需要按位运算符来管理它们并构造你想要的最终值。
见:
In [8]: print ssl.OP_NO_TLSv1, bin(ssl.OP_NO_TLSv1)
67108864 0b100000000000000000000000000
In [9]: print ssl.OP_NO_TLSv1_1, bin(ssl.OP_NO_TLSv1_1)
268435456 0b10000000000000000000000000000
In [13]: print ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1, bin(ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
335544320 0b10100000000000000000000000000
In [14]: print ssl.OP_NO_TLSv1 & ssl.OP_NO_TLSv1_1, bin(ssl.OP_NO_TLSv1 & ssl.OP_NO_TLSv1_1)
0 0b0
您会看到,如果您需要这两个选项,则需要将两个位都翻转为 1,因此需要一个 OR (|) 否则需要一个 AND (&),因为每个值只设置一个位到 1,每次在不同的位置,保证你总是得到 0 作为结果,这意味着根本没有特征,所以肯定不是你需要的。
简而言之,在这种组合值的情况下,您永远不会使用 AND (&)。
现在,关于&= ~:~ 是按位取反,因此删除一些选项同时保留已设置的其他选项很有用。
ctx.options &= ~ssl.OP_NO_SSLv3
此构造使您将最终值中与 ssl.OP_NO_SSLv3 相关的位翻转为 0。
见:
In [34]: ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
In [37]: print ctx.options, bin(ctx.options)
2197816319 0b10000011000000000000001111111111
In [38]: print bin(ssl.OP_NO_SSLv3)
0b10000000000000000000000000
In [40]: print ctx.options & ~ssl.OP_NO_SSLv3
2164261887
In [41]: print ctx.options & ~ssl.OP_NO_SSLv3, bin(ctx.options & ~ssl.OP_NO_SSLv3)
2164261887 0b10000001000000000000001111111111
如果您比较ctx.options 和ctx.options & ~ssl.OP_NO_SSLv3,您会看到一位已从1 翻转到0,因为您实际上删除了功能OP_NO_SSLv3。
如果我有上下文 ctx,如何设置 ssl.OP_NO_TICKET?我应该使用 = 还是 |= 还是 &=?请解释一下。
这是一个您想要添加到您已经拥有的所有其他选项的选项,因此您不想丢失它们。因此,您需要按位或 (|)。
- 如果你只做
= 你设置了这个选项但是失去了所有当前已经设置的其他选项,所以不是你需要的。
- 如果您执行
|=,您将与您想要的选项相关的位翻转为1,并且您不触及其他位;这就是你想要的!
- 如果你做
&= 你翻转到 1 只有那些位在你的新值和现有值中,这意味着如果该值尚未设置,则此处的结果只能为 0 或相同的确切值如果它已设置:
(我的示例是使用另一个值 OP_NO_TICKET 完成的,因为我没有它,但行为与任何一个都相同,因为每个 OP_ 值都是 2n , 即一位对一,所有其他对 0)
In [16]: ctx = ssl.OP_NO_TLSv1
In [17]: print ctx, bin(ctx)
67108864 0b100000000000000000000000000
In [19]: ctx = ssl.OP_NO_TLSv1_1
In [20]: print ctx, bin(ctx)
268435456 0b10000000000000000000000000000
In [21]: ctx = ssl.OP_NO_TLSv1
In [22]: ctx |= ssl.OP_NO_TLSv1_1
In [23]: print ctx, bin(ctx)
335544320 0b10100000000000000000000000000
In [24]: ctx = ssl.OP_NO_TLSv1
In [25]: ctx &= ssl.OP_NO_TLSv1_1
In [26]: print ctx, bin(ctx)
0 0b0
注意在| 的情况下这两个位是如何翻转为1。