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 |
如上所示
增加权限使用或(|)运算实现。
如,为用户增加“读取”、“写入”两种权限
读 | 写 | 执行 | > | 二进制 | > | 十进制 | 描述 |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | > | 000 | > | 0 | 已有权限(没有任何权限) |
1 | 0 | 0 | > | 100 | > | 4 | 待增加的权限,读 |
0 | 1 | 0 | > | 010 | > | 2 | 待增加的权限,写 |
用户现有的权限码为0,为其增加“读取”、“写入”两种权限,即4,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)。