Back to Programming Articles

A Closer Look at Bitfields
by Guest190829 04 Jan 2008
Rating: (1 vote - 5.00 average)

This article is helpful if you are curious about the internals of vBulletin permission checking. Sorry about the small thumbnails in advanced! Just click on them to enlarge.

Introduction

Do you find yourself copying and pasting the following code and not knowing the true internals of what it means?

PHP Code:
if(!($permissions['myhackpermissions'] & $vbulletin->bf_ugp['myhackpermissions']['canaddsomething'])) 
From the looks of it, you could probably identify that it involves permissions and if you read some of the great articles on vBulletin.org already regarding permissions, you probably know that this code is checking if a user has permissions for a certain custom modification action.

But what exactly is this code doing; what is the if condition truly evaluating?

Playing Detective

First let us echo out these two variables as if they actual existed:

PHP Code:

echo $permissions[‘myhackpermissions’];
// prints out 4
 
echo $vbulletin->bf_ugp['myhackpermissions']['canaddsomething'];
//prints out 1 
Seeing that both the variable are numbers, you may assume that the ampersand (&) in the if condition is performing some sort of arithmetic to the two numbers, and you would be correct.

The & in PHP (and other programming languages) is called a http://www.php.net/language.operators.bitwise , and it returns the bits that are both set in the two numbers. If you are confused, don't worry!

What is a Bit and Bitfield?
  • A bit is simply a binary digit and since binary is a base 2 numerical system, the only possible values of a bit is either 0 and 1.
  • A bitfield is simple just a field of bits such as: 1001, more importantly, a bitfield in programming represents a field of yes/no options that can be checked and manipulated.
Going back to the original code and the values of variables, what does bits and bit fields have to do with the numbers 4 ($permissions[‘myhackpermissions’]) and 1 ($vbulletin->bf_ugp['myhackpermissions']['candosomething']) ?

Integers as binary values


Any integer can be represented as a binary digit. The two values above are all divisible by 2, and so they can both be easily represented as a binary numeral, however, even larger and odd numbers can be defined as binary numbers.

Let us convert the two values into binary:

1 = 001
4 = 100

Now, I am not going to go in depth into the conversion of base 10 numerals to base 2, but the basics can be achieved with a table. Since binary is base 2, each bit is a multiple of two starting from 1.

&d=1199470611" rel="Lightbox_1415440" id="attachment74187

Enough with the math, how does this relate to Permissions?!

When creating an bitfield xml for your modification, you increase the number in between the <bitfield> </bitfield> by a multiple of two. Why? Because it can be represented as a bitfield!

Let’s take a look at a sample xml snippet:

Code:
<group name="myhackpermissions">
                <bitfield name="candosomething" group="my_hack_permissions"  phrase="canaddsomething”>1</bitfield>
                <bitfield name="candeletesomething" group="my_hack_permissions"  phrase="candeletesomething">2</bitfield>
                <bitfield name="canviewsomething" group="my_hack_permissions"  >4</bitfield>
</group>
The addition of all the values between the <bitfield></bitfield> tags is 7 (1 +2 + 4):

Using the attached table above, we see that 7 represented in binary is:

1 1 1

Now, imagine that as some sort of toggling board to enable each permission. If it is set to 1 then the user has permission to do that action. Conversely, if it is set to 0 then the user does not have permission to do that action.

So let us say that the if condition being evaluated above is for a guest and the guest is trying to add something to the database.

The administrator has selected that guest can only viewsomething. If we go back to the binary representing of group of permissions:

&d=1199470611" rel="Lightbox_1415440" id="attachment74185

The binary representation of the usergroup Guest’s permissions visually are:

&d=1199470611" rel="Lightbox_1415440" id="attachment74186

Recall the ampersand (&) returns the bits that set in both values:

PHP Code:
$permissions['myhackpermissions'] & $vbulletin->bf_ugp['myhackpermissions']['canaddsomething']) 
  • $permissions['myhackpermissions'] is the integer representation of all the “yes” permissions that the user has for the specific modification. If this user were an Admin and had permissions to do everything, the value in this variable would be 7 (4 + 2 + 1), however, as we saw when we played detective earlier, the value of this variables is only 4.
  • $vbulletin->bf_ugp['myhackpermissions']['canaddsomething'] is pointing to a specific key in the array of each individual bitfield. This array is just the XML you create in bitfield_myhack.xml parsed in array.
With the example XML data given earlier, the array would look something like:

PHP Code:

/**
   *This is just a visual representation. 
   *vBulletin parses the bitfield xml file via the bitfield_builder classes 
   *and determines the user's permissions with the function 
   *cache_permissions() in   functions.php
 */

$permissions['myhackpermissions'] = array(
     
'canaddsomething' => 1,
     
'candeletesomething' => 2,
     
'canviewsomething' => 4
); 
So $vbulletin->bf_ugp['myhackpermissions']['canaddsomething'] is pointing to the bitfield 1.

The if condition is basically checking if the canaddsomething bit is set to yes in the users permissions.

We can easily perform the bitwise AND operation (&) by vertically aligning the two values in binary form. If any equal bits are both set to 1 that bit is set to 1 in the result, otherwise it is set to 0.

4 = 1 0 0
1 = 0 0 1
====
0 0 0

The result is 0, which converted to a boolean means false, and therefore means that the current user does not have permission to “addsomething”.

Why Bitfields are Optimal

Think of using bitfields as a pseudo database table. Instead of having to add individual columns to the user table for every possible permission, an integer such as 131072 can represent a table of yes/no (1/0) options by converting it a binary number.

Using bitfields saves space and memory and is very popular method in handling permission systems across many programming languages because computers are very efficient in handling binary data.

Other articles on adding custom Permissions with Bitfields

Now go, go use the magic of bitfields in your next modification with the help of the following great articles!

[How-To] Create User Options (via Bitfields)
[How-To] Create Multiple Options Per Forum (via Bitfields)
[How-To] Create Usergroup Permissions (via Bitfields)

By: Danny Cassidy

vblts.ru supports vBulletin®, 2022-2024