Jump to content

[SOLVED] Bitwise Operations - Turning a bit OFF?


doni49

Recommended Posts

I'm writing user management script.  I'm working on the permissions system at the moment.

define("read",   "0000000000000001");
define("create", "0000000000000010");
define("delete", "0000000000000100");
define("modify", "0000000000001000");
define("control","0000000000010000");
//additional bit settings for future growth.
//define("","0000000000000000");
$rd = read | create;
$rd = $rd | delete | modify;
echo $rd . "<br><br>";

The above DOES display 0000000000001111.  So I have confirmed that I'm able to set each individual permission.

 

But the following displays as a funky character--a triangle with a question mark in the middle of it (in FF2 ONLY--IE7 displays NOTHING).  I EXPECTED it to display as 0000000000001110.

 

$rd = $rd & ~read;
echo $rd;                                              //<--This returns just ONE of those strange characters.
echo "<br><br>Test:  " . $rd . "<br><br>";  //<--This returns "Test:  " followed by a BUNCH of those strange characters.

 

Here's a screen shot of exactly what I'm seeing (from FF2).

Bitwise-FF2.jpg

 

here's a screen shot from IE7.

Bitwise-IE6.jpg

Link to comment
Share on other sites

I'm not sure about this but I believe some of the bitwise operators don not implicitly convert your strings to integers. Try to use intval():

 

$rd = intval($rd) & ~intval(read);

 

If this works, to ease your code, do the translation on the defines, and comment them with the string if you wish.

 

define("read",   0x1); // 0000000000000001
define("create", 0x2); // 0000000000000010
define("delete", 0x4); // 0000000000000100
define("modify", 0x8); // 0000000000001000
define("control", 0x10); // 0000000000010000

 

EDIT: Corrected the defines to their hexadecimal counterparts

Link to comment
Share on other sites

Also--for calculating the hex values, can I just use windows calculator?

 

i.e. in bin mode, type in my binary string and then switch it to hex mode.

 

I just tested a string and the binary string of 11111 converts to a hex value of 1f.  I'm assuming that would be 0x1F.

 

EDIT:  I ask this because I can visualize it better when viewing the binary string like I was entering.

Link to comment
Share on other sites

If using bitwise, work with bits and nor chars

 

<?php
define("READ",   0x0001);
define("CREATE", 0x0002);
define("DELETE", 0x0004);
define("MODIFY", 0x0008);
define("CONTROL",0x0010);


$rd = READ | CREATE;
$rd = $rd | DELETE | MODIFY;
echo decbin($rd) . "<br><br>";

$rd = $rd &~READ;
echo decbin($rd) . "<br><br>";

?>

 

can I just use windows calculator?

yes

Link to comment
Share on other sites

I just tested a string and the binary string of 11111 converts to a hex value of 1f.  I'm assuming that would be 0x1F.

 

EDIT:  I ask this because I can visualize it better when viewing the binary string like I was entering.

 

Yes, that would be 0x1f. I too find it easier to visualize the "bits string", hence me suggesting you to leave it as a comment on the definition of those constants.

 

However, when doing the translation to an integer, do not feel tempted to use base 10. Use instead hexadecimals as demonstrated by us. You will see that conversions from hexadecimal to binary are much easier to do in your head. After a while you may be able to even do it without much thinking and you no longer will need those bit strings as a comment.

Link to comment
Share on other sites

I just tested a string and the binary string of 11111 converts to a hex value of 1f.  I'm assuming that would be 0x1F.

 

EDIT:  I ask this because I can visualize it better when viewing the binary string like I was entering.

 

Yes, that would be 0x1f. I too find it easier to visualize the "bits string", hence me suggesting you to leave it as a comment on the definition of those constants.

 

However, when doing the translation to an integer, do not feel tempted to use base 10. Use instead hexadecimals as demonstrated by us. You will see that conversions from hexadecimal to binary are much easier to do in your head. After a while you may be able to even do it without much thinking and you no longer will need those bit strings as a comment.

 

Uh... you can use BASE 10.

<?php
define("READ",   1);
define("CREATE", 2);
define("DELETE", 4);
define("MODIFY", ;
define("CONTROL", 16);


$rd = READ | CREATE;
$rd = $rd | DELETE | MODIFY;
echo decbin($rd) . "<br><br>";

$rd = $rd &~READ;
echo decbin($rd) . "<br><br>";
?>

 

That is also what you're doing when setting the error reporting level. It uses the decimal system as well - check out the manual.

Link to comment
Share on other sites

Thanks guys!

 

What's the diff between these?  The first is from quiettech and the second is from Barand.  Do the extra zeros (in red below) do anything?  Should I be including them?

 

define("read",  0x1);

 

and

 

define("READ",  0x0001);

Link to comment
Share on other sites

Thanks but that still has me puzzled.  If it WAS on and I turned it off, wouldn't that still be the same?  If not, I might need to re-think how I'm doing things.

 

If I look at the current setting and it's now off, I wouldn't allow the user to read.

Link to comment
Share on other sites

Uh... you can use BASE 10.

 

Daniel, I meant write the number in hexadecimal format in the code. It helps translations into bit patterns in our head more than the decimal format does.

 

Plus--I can see the potential for a real problem:  What would happen if the READ and NOT_READ bits are both set?

 

What Barand is suggesting is to write your hexadecimal numbers following the bit size you are expecting to use on your operations. This is good advise. As such, even while 0x1 is essentially the same as 0x0001, the latter also tell reminds anyone reading the code, operations on those bits will be performed taking a 16 bit pattern as reference.

 

The issue of setting ON and OFF patterns is also good advise, if you find yourself using them all too often.

 

For instance, your user permissions system benefits if you also define NOT variants. This will allow you to skip the ~ operator almost everywhere.

Link to comment
Share on other sites

Uh... you can use BASE 10.

 

Daniel, I meant write the number in hexadecimal format in the code. It helps translations into bit patterns in our head more than the decimal format does.

 

I don't see why that's true.

 

1 = 00000001, 2 = 00000010, 4 = 00000100, 8 = 00001000, 16 = 00010000, 32 = 00100000, 64 = 01000000, 128 = 10000000 etc.

 

Each time you double the number represented in BASE 10 the bit which is turned on is moved one place to the left in BASE 2.

Link to comment
Share on other sites

What Barand is suggesting is to write your hexadecimal numbers following the bit size you are expecting to use on your operations. This is good advise. As such, even while 0x1 is essentially the same as 0x0001, the latter also tell reminds anyone reading the code, operations on those bits will be performed taking a 16 bit pattern as reference.

I eventually got that from his last response but thanks anyway.

The issue of setting ON and OFF patterns is also good advise, if you find yourself using them all too often.

That kind of makes sense to me but I'm defining a user class and one the class's methods will be to turn a specific right on or off.  It accepts a second argument (default is TRUE)--if this argument is TRUE then it turns the right on, if this argument is FALSE, it turns the right off.

 

There is another method that just finds out whether a right is on or off.

 

Thanks for all the assistance guys!  I'm going to mark this solved as all my questions have been answered.

Link to comment
Share on other sites

I don't see why that's true.

 

1 = 00000001, 2 = 00000010, 4 = 00000100, 8 = 00001000, 16 = 00010000, 32 = 00100000, 64 = 01000000, 128 = 10000000 etc.

 

Each time you double the number represented in BASE 10 the bit which is turned on is moved one place to the left in BASE 2.

 

Yes. But that's about it. There's not many more other relations you can establish.

 

On the other hand, if you look at it closely, each hexadecimal digit represents 4 bits. After a while of working with hexadecimal and binary representations you will mentally construct a full binary pattern from any hexadecimal representations without the help of a calculator or converter. All you have to get accustomed to is the binary representations of the 0 to F hexadecimal equivalents.

 

For instance:

 

0xA048FD is 10,504,445.

You have no way of taking 10504445 and quickly establish its binary representation without the help of some pen and paper, a calculator, or converter.

 

However 0xA048FD can easily be translated to binary if you simply convert each digit from left to right and append each of the resulting 4 bit patterns.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.