在某个业务场景中,需要判断某应用需要的权限,在之前,我很可能会使用if,else,或者switch语句来获取或者改变其某个权限的状态,今天了解到了还有通过巧用位运算中的按位异或和按位与来操作,真的是涨姿势了,话不多说先看代码:
1 | //以下声明了该应用需求的4个权限获取的状态,数值为2的整数幂的值,以便转换二进制来判断权限 |
该应用需要的权限
权限名 | 权限值 | 权限值(二进制) |
---|---|---|
READ_MSG | 1 | 0000 0001 |
DEL_MSG | 2 | 0000 0010 |
READ_TEL | 4 | 0000 0100 |
DEL_TEL | 8 | 0000 1000 |
①将权限码总和与需要查询的某权限的权限码做按位与运算
这里我选择了DEL_TEL这个权限,其权限码二进制为0000 1000,权限码总和为0000 1011
1 | 0000 1000 |
我们会发现按位与运算后的结果不等于0,表示其拥有DEL_TEL这个权限,再尝试换READ_TEL这个权限试验:
1 | 0000 0100 |
这时结果为0了,表示其没有READ_TEL的权限,确认无误。
②将权限码总和与需要改变的某权限的权限码做按位异或运算
1 | 0000 1000 |
这时候我们再用结果的0000 0011和其DEL_TEL权限码做按位与运算发现其DEL_TEL的权限没有了:
1 | 0000 0011 |
按位运算带来的影响
基于位运算实现权限管理系统时,其运算运算对象是二进制数,优点是:运算速度快、效率高、节省存储空间、对权限控制非常灵活。所有语言都提供了位运算符,我们可以在不同语言实现的系统、甚至数据库中使用位运算实现对用户权限的管理。
位运算也有一些局限性,随着权限码增加,数据长度也相应的增长。这就要求权限码不能超过计算本身运算长度,在数据库中存储权限码时,权限码长度也不能的超过所使用数据类型。如:在32位系统中不能超过232,也就是权限数量不能多于32个。而mySQL数据库的BIGINT,其存储空间为8Byte,使用BIGINT存储存储码时,权限数不能多于64个(8*8-1)。