Linux基于位运算的权限控制

Linux权限控制是基于位运算实现的。

在Linux权限系统中,读、写、执行权限分别对应三个状态位:

执行 ==> 二进制 ==> 十进制
0 0 1 ==> 001 ==> 1
0 1 0 ==> 010 ==> 2
1 0 0 ==> 100 ==> 4
0 1 1 ==> 011 ==> 3
1 0 1 ==> 101 ==> 5
1 1 0 ==> 110 ==> 6
1 1 1 ==> 111 ==> 7

如上所示

  • “执行”权限使用二进制为001,即:十进制1。
  • “写入”权限使用二进制为010,即:十进制2。
  • “读取”权限使用二进制为100,即:十进制4。

实现权限的添加(或运算)

增加权限使用或(|)运算实现。

如,为用户增加“读取”、“写入”两种权限

执行 ==> 二进制 ==> 十进制 描述
0 0 0 ==> 000 ==> 0 已有权限(没有任何权限)
1 0 0 ==> 100 ==> 4 待增加的权限,读
0 1 0 ==> 010 ==> 2 待增加的权限,写

用户现有的权限码为0,为其增加“读取”、“写入”两种权限,即4,2
使用或运算结果如下

1
2
0|4=4 //增加读取权限
4|2=6 //增加写入权限

实现权限的减少(非运算)

位运算同样可以实现用户权限的减少,减少用户权限使用非(^)运算。
如,将权限码为7用户,移除执行权限:

执行 ==> 二进制 ==> 十进制 描述
1 1 1 ==> 111 ==> 7 已有权限
1 0 0 ==> 100 ==> 4 待判断的权限,读

权限码7(111)和1(001)的非运算结果为6,即:7^1=6。
权限码6,则为权限码7移除执行后的权限码。

实现权限的判断(与运算)

在需要进行用户权限判断时,可以使用与(&)运算判断用户是否具有某项权限。

如,判断权限码为6用户是否有“读取”,“执行”权限:

执行 ==> 二进制 ==> 十进制 描述
1 1 0 ==> 110 ==> 6 已有权限
1 0 0 ==> 100 ==> 4 待判断的权限,读
0 0 1 ==> 001 ==> 1 待判断的权限,执行

权限码6(110)和4(100)的与运算结果为4,即:6&4=4。
权限码6(110)和1(001)的与运算结果为0,即:0=6&1。

根据与运算的计算规律,当运算结果为所要判断权限本身值时,我们可以认为用户具有这个权限。而当运算结果为 0 时,我们可以认为用户不具有这个权限。

优点和缺陷

位运算的运算对象是二进制的位,速度快,效率高,而且节省存储空间,位运算做权限控制又相当地灵活。但是,位运算也有很大的局限,因为在32位计算机上,位移不能超过32次,这就要求权限数量不超过32种。而mySQL数据库的BIGINT,其存储空间为8Byte,使用BIGINT存储存储码时,权限数不能多于64个(8*8-1)。