Understanding bitwise code

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

pilau
Forum Regular
Posts: 594
Joined: Sat Jul 09, 2005 10:22 am
Location: Israel

Understanding bitwise code

Post by pilau »

Hi,

I'm currently learning how vBulletin works and I've hit a hurdle on the permissions system they have in place.

They have an array like such:

Code: Select all

<?php

// field names for administrative permissions

$_BITFIELD['usergroup']['adminpermissions'] = array(
   'ismoderator'           => 1,
   'cancontrolpanel'       => 2,
   'canadminsettings'      => 4,
   'canadminstyles'        => 8,
   'canadminlanguages'     => 16,
   'canadminforums'        => 32,
   'canadminthreads'       => 64,
   'canadmincalendars'     => 128,
   'canadminusers'         => 256,
   'canadminpermissions'   => 512,
   'canadminfaq'           => 1024,
   'canadminimages'        => 2048,
   'canadminbbcodes'       => 4096,
   'canadmincron'          => 8192,
   'canadminmaintain'      => 16384,
   'canadminupgrade'       => 32768
);

?>
Now I can see that those numbers are all base2 numbers and it starts to make sense when you see how they check the permissions:

Code: Select all

<?php

// final bitfield check on each permission we are checking

   foreach($do AS $field)
   {
      if ($adminperms & $_BITFIELD['usergroup']['adminpermissions']["$field"])
      {
         return true;
      }
   }

?>
So if bits are set in the array AND set in the variable $adminperms then the user has access to administrate, otherwise, they don't.

I understand the basics of the mathematics but I don't understand exactly how it works. For example, if I wanted to add a new permission I guess I would just add the next base2 value to the array for the permissions but I don't understand how and why it works :(
duk
Forum Contributor
Posts: 199
Joined: Wed May 19, 2004 8:45 am
Location: London

Post by duk »

is just a array, with two columns and some rows...

the foreach just search in the array if finds the base 2 Number of the permission... yes if you want to add a new permission you just need to add the new base 2 number...

but you need to remember that maybe there is other scripts based in the current permissions, and if you add a new permission, you need to check how the all application works arround this permissions in way to add new permissions...
pilau
Forum Regular
Posts: 594
Joined: Sat Jul 09, 2005 10:22 am
Location: Israel

Post by pilau »

duk wrote:but you need to remember that maybe there is other scripts based in the current permissions, and if you add a new permission, you need to check how the all application works arround this permissions in way to add new permissions...
Yes this is exactly what I was worried about. How can I know what number is safe to add as a new permission?
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

Semantics matter, arrays do not have rows or columns.

That aside think of it like this

Code: Select all

perm 1   perm 2
1            0

perm 1 is on and perm2 is off. This would be binary 10 or "2", you would just add more bits to add permissions

Code: Select all

perm 1 perm 2 perm 3
0          1          1


011   = "3"
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

pilau wrote:
duk wrote:but you need to remember that maybe there is other scripts based in the current permissions, and if you add a new permission, you need to check how the all application works arround this permissions in way to add new permissions...
Yes this is exactly what I was worried about. How can I know what number is safe to add as a new permission?
You assume that anyone else who modifies the code adds their permission bit in the same place you just specified...so you can see the max permission bit and add another one...
duk
Forum Contributor
Posts: 199
Joined: Wed May 19, 2004 8:45 am
Location: London

Post by duk »

jshpro2 wrote:Semantics matter, arrays do not have rows or columns.

That aside think of it like this

Code: Select all

perm 1   perm 2
1            0

perm 1 is on and perm2 is off. This would be binary 10 or "2", you would just add more bits to add permissions

Code: Select all

perm 1 perm 2 perm 3
0          1          1


011   = "3"
in school i learn that arrays works with columns and rows... indexed at 0, and vectors are just simple rows... like a database have their columns and rows, its works as arrays..
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

Arrays can be *thought* of as tables (with rows) when you are describing 2d data with them

Code: Select all

array =>
(
     [0] => array
     (
           [0] =>  5
     )
)

What would you call the "5"? 'row 0 column 0 row 0 column 0' ?
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

pilau wrote:
duk wrote:but you need to remember that maybe there is other scripts based in the current permissions, and if you add a new permission, you need to check how the all application works arround this permissions in way to add new permissions...
Yes this is exactly what I was worried about. How can I know what number is safe to add as a new permission?
Well, as you have already noticed... they are all another power of 2. 2^0, 2^1, ... So you would have to add 2^n for a n-th permission... If you look at it binary wise you end up with:

1 <- (n - 2) other bits set to 1 -> 1

Now you have the situation where all n permissions are set..
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

For any given user you just add up the values of each individual permission to get their own permissions value.

So let's say Joe Bloggs needs 'ismoderator' and 'canadminstyles' but nothing else we would add up their values. This gives him 1 + 8 == 9.

Now you can check if he has each of the permissions by simply doing what you see in that foreach loop. Bits that are set in BOTH the user permissions and the system value in the array.

So for is moderator (yes)

Code: Select all

16      8      4       2       1
-----------------------------------------------------
9                      1     0       0       1
1                                               1

9&1                 0      0       0       1      == 1
cancontrolpanel (No)

Code: Select all

16      8      4       2       1
-----------------------------------------------------
9                      1     0       0       1
2                                      1       0

9&2                 0      0       0       0      == 0
'canadminsettings' (No)

Code: Select all

16      8      4       2       1
-----------------------------------------------------
9                      1     0       0       1
4                              1      0       0

9&4                 0      0       0       0      == 0
'canadminstyles' (yes)

Code: Select all

16      8      4       2       1
-----------------------------------------------------
9                      1     0       0       1
8                      1     0       0       0

9&4                  1      0       0       0      == 8
Hopefully that makes sense :)
AGISB
Forum Contributor
Posts: 422
Joined: Fri Jul 09, 2004 1:23 am

Post by AGISB »

Ok I would not understand it if I just read the explaintion here ;)

I try it in laymans terms

So you double the number for each permission: 1, 2 ,4 ,8 , 16 ....

As example your user gets a permission number of 29.


Now you start with your highest permission number in this example it is 16


Now check if the number (16) <= 29

yes mark the permission as yes take the rest by 29 - 16 = 13

now go to the next number (8 ) <= 13
yes mark the permission as yes take the rest by 13 - 8 = 5

now go to the next number (4) <= 5
yes mark the permission as yes take the rest by 5 - 4 = 1

now go to the next number (2) <= 1
no mark it as no keep the number

now go to the next number (1) <= 1
yes mark the permission as yes finish
pilau
Forum Regular
Posts: 594
Joined: Sat Jul 09, 2005 10:22 am
Location: Israel

Post by pilau »

So all I have to do is just add the next base2 number?
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

Yeah, that's right, but its good to understand the math first so you know what you're doing
pilau
Forum Regular
Posts: 594
Joined: Sat Jul 09, 2005 10:22 am
Location: Israel

Post by pilau »

You mean I should check if it clashes with other permissions?
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

pilau wrote:You mean I should check if it clashes with other permissions?
No... He just meant it's good to understand how it works... you've already done that I believe :)
pilau
Forum Regular
Posts: 594
Joined: Sat Jul 09, 2005 10:22 am
Location: Israel

Post by pilau »

Sorry if I am starting to repeat myslef. But at vBulletin they said that messing around with this array could cause some serious bugs. So, all that I need to do is just add the next base2 number and worry?
Post Reply