Reputation: 100
I'm building a system where I need to assign users access to a specific (individual) number of assets. These assets (potentially numbering in the tens of thousands).
I thought to do it with bitwise comparisons, so something like storing the value of 3 if a user has access to assets 1 and 2, a value of 7 for access to 1, 2 and 3, etc. etc.
The access is not necessarily sequential, so a user could easily have access to assets 10, 12 and 24324.
I quickly ran into a problem using bits where the server wouldn't pick up assets beyond the 63rd bit, so obviously I've either misunderstood something, or bits is a dumb way to store this kind of info.
My code, running on a 64-bit Linux system, is this (just for testing purposes obviously, to discover just such limitations as this):
<?php
$bitwise = $_GET['bitwise'];
if (isset($bitwise)) {
echo "<br/>bitwise input: ";
echo $bitwise;
$bitcount = 0;
for ($i=1;$i<=$bitwise;$i*=2) {
if (($i & $bitwise) > 0) {
$bitcount++;
echo "<br/>{$bitcount}: " . $i . " is in " . $bitwise;
}
}
}
?>
And I input test values via the querystring. However, no matter what value I input, the maximum count I can get to is 63.
So, my question is: Is this simply because I'm using bitwise comparisons for something they're not ideal for (my theory), or is my implementation of it just wrong?
My next go-to solution would be to store the "bits" in arrays, so if someone has access to assets 1, 2 and 3 I'll store their list as [1,2,3]. It's unlikely that someone has access to more than, say, a hundred specific assets. Is this a reasonable way to do it? I realize this puts the question somewhat into discussion-worthy territory, but hopefully it's still specific enough.
Paramount concerns are, of course, performance if the server has to serve a large number of clients at the same time.
(please excuse wrong terminology where applicable, hopefully my meaning is clear).
Upvotes: 1
Views: 248
Reputation: 166106
This is standard behavior — on 64 bit compiled PHP, integers have a maximum length of 64 bits. While it warms my secret grey beard heart, if you have more than 64 different roles, a bitwise solution is the wrong one for access control.
Two other things worth mentioning.
First, doing this for performance reasons is probably a premature optimization for a web application. ACL lookups aren't going to be the bottleneck in your system for a long time, if at all. Also, it's not clear if bitwise operators offer that much PHP performance benefit, given the language's dynamically typed nature.
Second, the reason you're limited to 63 bits is because PHP (appears to?) use Two's compliment for their implementation of signed integers. The final bit is for representing positive or negative numbers. I asked this question about the bitwise NOT
a while back, which is why this question caught my eye.
Upvotes: 2