Page 1 of 2
Understanding bitwise code
Posted: Mon Jan 30, 2006 1:34 pm
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

Posted: Mon Jan 30, 2006 2:09 pm
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...
Posted: Mon Jan 30, 2006 2:22 pm
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?
Posted: Mon Jan 30, 2006 2:29 pm
by josh
Semantics matter, arrays do not have rows or columns.
That aside think of it like this
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"
Posted: Mon Jan 30, 2006 2:30 pm
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...
Posted: Mon Jan 30, 2006 2:41 pm
by duk
jshpro2 wrote:Semantics matter, arrays do not have rows or columns.
That aside think of it like this
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..
Posted: Mon Jan 30, 2006 2:46 pm
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' ?
Posted: Mon Jan 30, 2006 3:37 pm
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..
Posted: Mon Jan 30, 2006 4:35 pm
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

Posted: Tue Jan 31, 2006 12:29 am
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
Posted: Tue Jan 31, 2006 11:30 am
by pilau
So all I have to do is just add the next base2 number?
Posted: Tue Jan 31, 2006 11:59 am
by josh
Yeah, that's right, but its good to understand the math first so you know what you're doing
Posted: Tue Jan 31, 2006 12:48 pm
by pilau
You mean I should check if it clashes with other permissions?
Posted: Tue Jan 31, 2006 12:55 pm
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

Posted: Tue Jan 31, 2006 1:02 pm
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?