我有一个以前由其他人构建的 ACL 系统,我正在尝试了解位屏蔽是如何工作的。我定义了这 4 个常量:
const NONE = 0;
const READ = 1;
const WRITE = 2;
const UPDATE = 4;
const DELETE = 8;
然后在数据库中,我看到具有 1、2、5、9、15 等权限的用户。我尝试使用这个工具对它们进行转换,最终得到以下结果:
0 // NONE
1 // READ
2 // WRITE
3 // UPDATE|DELETE
4 // UPDATE
5 // WRITE|DELETE
6 // WRITE|UPDATE
7 // WRITE|UPDATE|DELETE
8 // DELETE
9 // READ|DELETE
10 // READ|UPDATE
11 // READ|UPDATE|DELETE
12 // READ|WRITE
13 // READ|WRITE|DELETE
14 // READ|WRITE|UPDATE
15 // READ|WRITE|DELETE|UPDATE
我对这个作品的看法如下:
Decimal Hexadecimal
3 00000011
因为最后两位是
1
,我假设那些拥有 3
的用户将拥有 UPDATE|DELETE
权限(见上表)。是对的吗?如果不是,从十进制转换为位掩码的正确方法是什么?
0 = NONE
是一种特殊情况,可以通过简单的比较来检查。
如果你想问的问题是常量
cn
并且设置了 2^(n-1)
的值,那么我们可以用 (1 = yes, 0 = no, % = modulo):
(value / cn) % 2
如果我们想要获取所有已设置的标志,可以使用以下伪代码来实现:
c := 1
while value > 0
if value % 2 = 1
// constant c is set
...
end if
value := value / 2
c := c * 2
end while
我知道这已经有很多年了,但没有看到解决方案让我很烦恼。
如果我必须评分:
0 // NONE
1 // READ
2 // WRITE
X 3 // UPDATE|DELETE
4 // UPDATE
X 5 // WRITE|DELETE
6 // WRITE|UPDATE
X 7 // WRITE|UPDATE|DELETE
8 // DELETE
9 // READ|DELETE
X 10 // READ|UPDATE
X 11 // READ|UPDATE|DELETE
X 12 // READ|WRITE
X 13 // READ|WRITE|DELETE
X 14 // READ|WRITE|UPDATE
15 // READ|WRITE|DELETE|UPDATE
我不太明白权限如何“最终得到这个结果”。我唯一能想到的是“0”被视为值之一 - 从而混淆了值 - 当它实际上缺乏任何启用的值时,意味着实际上没有访问权限。
相反,将 2 的倍数常量视为位开关,每个开关都可以独立启用 (1)/禁用 (0),每个开关都使用以下位置值相加相乘:
8421
示例:
0000 是 0+0+0+0 或无法访问
0011 是 0+0+2+1 或读/写
1001 是 8+0+0+1 或读取/删除
我对这个作品的看法如下:
Decimal Hexadecimal 3 00000011
十六进制和二进制在这里很容易混淆。其实是:
Decimal Hex Binary
3 03 00000011
鉴于此,完整列表将翻译为:
_______________________________
| ______________________ |
|| _____________ | |
||| ____ | | |
|||| | | | |
Value 8421 READ WRITE UPDATE DELETE Effect
----- ---- ------ ------ ------ ------ ------
0 0000 No Access
1 0001 READ Read-Only (view)
2 0010 WRITE Write-Only (dropbox-like: add new, no other access)
3 0011 READ WRITE Read/Write (view exiting; add new)
4 0100 UPDATE Update-Only (update existing, difficult to imagine an application without read)
5 0101 READ UPDATE Read/Update (view, update existing)
6 0110 WRITE UPDATE Write/Update (add new; update existing)
7 0111 READ WRITE UPDATE Read/Write/Update
8 1000 DELETE Delete-Only (difficult to imagine an application without read)
9 1001 READ DELETE Read/Delete
10 1010 WRITE DELETE Write/Delete
11 1011 READ WRITE DELETE Read/Write/Delete
12 1100 UPDATE DELETE Update/Delete
13 1101 READ UPDATE DELETE Read/Update/Delete
14 1110 WRITE UPDATE DELETE Write/Update/Delete
15 1111 READ WRITE UPDATE DELETE Full-Access