如何将十进制转换为位掩码?

问题描述 投票:0回答:2

我有一个以前由其他人构建的 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
权限(见上表)。是对的吗?如果不是,从十进制转换为位掩码的正确方法是什么?

hex decimal bitmask bit-masks
2个回答
1
投票

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
投票

我知道这已经有很多年了,但没有看到解决方案让我很烦恼。

如果我必须评分:

   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
© www.soinside.com 2019 - 2024. All rights reserved.