如何利用位运算做逻辑控制

位运算符号简介

1
2
3
4
5
6
7
8
& 与运算   两者为1时  为1:  0b0010 & 0b0011 = 0b0010
| 或运算 一着为1时 为1: 0b0010 & 0b1011 = 0b1011
^ 异或运算 两者不同时 为1: 0b0101 & 0b1011 = 0b1110
! 取反运算 每位取反 : !0b1010 = 0b0101

PS:
0b1010为二进制表达
常见的位运算符有: & | ! ^ << >> 等, 建议花一些时间了解一下

应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
案例1: 如何用 一个字段管理4个权限: 权限1、权限2、权限3、权限4

解决方案:
用一个二进制数来表达权限 二进制位为1时表示有权限 0无权限
将有权限1定义为 0b0001
将有权限2定义为 0b0010
将有权限3定义为 0b0100
将有权限4定义为 0b1000

综上: 若一个用户拥有权限1234, 则表达为 0b1111

1: 赋权(|: 或运算 两者有1时为1)
role = 0b0010 //用户权限
role = role | 0b0001 //赋予用户权限1 -> role = 0b0011
role = role | 0b1000 //赋予用户权限4 -> role = 0b1011

2: 去权(^: 异或运算 两者不同时为1)
role = 0b1011 //用户权限
role = role ^ 0b0010 //移去用户权限2 -> role = 0b1001
role = role ^ 0b1000 //移去用户权限4 -> role = 0b0001

3: 判权(&: 与运算 两者为1时为1)
role = 0b1011 //用户权限
role & 0b0001 > 0 //有权限1
role & 0b0010 > 0 //有权限2
role & 0b0100 = 0 //无权限3
role & 0b1000 > 0 //有权限4

经典案例 LINUX文件权限管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
~/temp: ls -l
-rw-r--r-- demofile
解析: -rwxrw-r--, 其中
第1位表示 demofile 为一个文件
第234位表示 文件所有者的权限是读、写和执行
第567位表示 与文件所有者同一组的用户的权限是读、写但不能执行
第890位表示 不与文件所有者同组的其他用户的权限是读不能写和执行

关于LINUX文件权限 和用户组建议单独了解一下

若想给demofile赋权为 全部权限 应该怎么做?
chmod 777 demofile
此处的7对应0b111 --> 对应 r w x 三权限
三个7分别对应 所有者、同组用户、其他用户三者权限
所以chmod 777 demofile后,该文件权限变成了
rwxrwxrwx

在MYSQL中使用

1
2
3
4
5
6
7
8
9
首先创建一张表,role字段用INT类型即可
得到一张userRole表为:
userId INT
role INT
若想查出所有 拥有0b0010对应权限的用户们时
SELECT userId from userRole where role & 2 > 0;
即可: 2为0b0010的十进制表达

后续如果添加了权限, 只需要在最新的值前面不断补0即可

总结

1
2
3
位运算表达,不仅可以用在权限中,其他例如开关、是否占用等等可以用01表示单位逻辑的情况均可使用

本POST仅为基础的思路介绍和简单伪代码,若正常使用,仍需做更多层的封装和维护

如何利用位运算做逻辑控制
https://yaocc.cc/bitcontrol/
作者
Yaocan Chen
发布于
2021年5月20日
许可协议