Linux的文件权限设计思想

1
2
[lavenderuni@~]# ls -l bitauth.md
-rw-r--r-- 1 lavenderuni staff 1137 10 25 14:43 bitauth.md
  • 0 — 表示没有权限,二进制为000
  • 1 –x 表示有执行权限,二进制为001
  • 2 -w- 表示有写权限,二进制为010
  • 3 -wx 表示有写和执行权限,二进制为011
  • 4 r– 表示有读权限,二进制为100
  • 5 r-x 表示有读和执行权限,二进制为101
  • 6 rw- 表示有读和写权限,二进制为110
  • 7 rwx 表示有读、写和执行权限,二进制为111

假如给定一个数字6,3,4,如何判定在这个数字里面包含某一种权限呢?

bit运算

  • 读权限 r=4,二进制表示为100
  • 写权限 w=2,二进制表示为010
  • 执行权限x=1,二进制表示为001

6表示为110
110 & 100 = 100 = 4 !=0 有读权限
110 & 010 = 010 = 2 !=0 有写权限
110 & 001 = 000 = 0 ==0 没有执行权限

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
28
29
30
#!/usr/bin/env python
# coding:utf-8
def bit_judge(auth_num):
auth_r = 4
auth_w = 2
auth_x = 1
auth_str = ''
if auth_num & auth_r == 0:
auth_str += '-'
else:
auth_str += 'r'
if auth_num & auth_w == 0:
auth_str += '-'
else:
auth_str += 'w'
if auth_num & auth_x == 0:
auth_str += '-'
else:
auth_str += 'x'
return auth_str
if __name__ == '__main__':
print bit_judge(4)
print bit_judge(6)

相除求余

6表示为110
(6 / 4) % 2 ==1 有读权限
(6 / 2) % 2 ==1 有写权限
(6 / 1) % 2 ==0 没有执行权限

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
28
29
30
31
#!/usr/bin/env python
# coding:utf-8
def dividemod_judge(auth_num):
auth_r = 4
auth_w = 2
auth_x = 1
auth_str = ''
if (auth_num / auth_r) % 2 == 1:
auth_str += 'r'
else:
auth_str += '-'
if (auth_num / auth_w) % 2 == 1:
auth_str += 'w'
else:
auth_str += '-'
if (auth_num / auth_x) % 2 == 1:
auth_str += 'x'
else:
auth_str += '-'
return auth_str
if __name__ == '__main__':
print dividemod_judge(6)
print dividemod_judge(4)

思考

mysql中数据设计类似权限数据,或者动态tag数据,都可以用多个bit位表示,是不是可以不用关联表,将数据降维,放在一个字段存储呢

公开 = 1
加密 = 2
封锁 = 4
置顶 = 8

  • 公开blog 给status进行或运算
    update blog set status = status | 1;
  • 加密blog 给status进行或运算
    update blog set status = status | 2;
  • 封锁blog
    update blog set status = status | 4;
  • 解锁blog
    update blog set status = status ^ 4;
  • 查询所有被置顶的blog
    select from blog where status & 8;
    等价于select
    from blog where (status & 8) != 0;

缺点是查询的时候没有办法使用索引,因为位运算无法移动到=号的右边。