Search code examples
hexdecimalbitmaskbit-masks

How to translate from decimal to bit-mask?


I have a ACLs system previously built by someone else and I am trying to understand how bit-masking works there. I have this 4 constants defined:

const NONE = 0;
const READ = 1;
const WRITE = 2;
const UPDATE = 4;
const DELETE = 8;

Then in DB I am seeing users with permissions like 1, 2, 5, 9, 15. I have tried to transform them using this tool and I end up with this result:

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

How I think this work is as follow:

Decimal    Hexadecimal
3          00000011

Because the two last bits are 1 I am assuming that those users having 3 will have UPDATE|DELETE permissions (see table above). Is that right? If not what's the right way to translate from decimal to bit-mask?


Solution

  • 0 = NONE is a special case which can be checked by simple comparison.

    If you want to ask the question is constant cn with the value of 2^(n-1) set, then we do this with (1 = yes, 0 = no, % = modulo):

    (value / cn) % 2
    

    If we want to get all flags that are set, you can do this with the following pseudo code:

    c := 1
    while value > 0
        if value % 2 = 1
            // constant c is set
            ...
        end if
        value := value / 2
        c := c * 2
    end while