Reputation: 1606
I have no idea why i get two different results from the same function, When i use it in local host i get a result and when i upload file to my host i get different result. I test it, i give it the same word and i get two different results. it's a function from CAPTCHA library: Captcha library
function rpHash($value) {
$hash = 5381;
$value = strtoupper($value);
for($i = 0; $i < strlen($value); $i++) {
$hash = (($hash << 5) + $hash) + ord(substr($value, $i));
}
return $hash;
}
Upvotes: 2
Views: 270
Reputation: 5670
The problem is that your localhost is 32bit and your host is 64bit. To understand why, read the accepted answer on this post. To summarize:
The << operator does a Left shift
Integers are stored, in memory, as a series of bits. For example, the number 6 stored as a 32-bit int would be represented in base 2 as:
00000000 00000000 00000000 00000110
Shifting this bit pattern to the left one position (6 << 1) would result in the number 12 and represented in base 2 as:
00000000 00000000 00000000 00001100
As you can see, the digits have shifted to the left by one position, and the last digit on the right is filled with a zero.
When you shift left, you are increasing the number by an order of ^2 for each shift.
On a 32 bit system, the maximum integer you can have is 2,147,483,647 (which is 01111111 11111111 11111111 11111111 (there are 31 bits available). That is how much room you have to shift left before you run out of room to store the number.
Your starting hash of 5381 is 13 bits long Your function shifts FIVE bits for each letter in the $value. You get to 31 bits after 3 letters (3*5) + 13 = 28
So you can only have 3 letters max in your CAPTCHA before it breaks. Your OPTIONS:
Restrict your CAPTCHA to 3 characters or less and use the existing function.
Shift using $hash << 3
. This will get you 5
characters
Shift using $hash << 2
. This will get you 7
characters
Use a different method
For example:
function rpHash($value) {
$hash = 5381;
$value = strtoupper($value);
for($i = 0; $i < strlen($value); $i++) {
$hash = (($hash << 2) + $hash) + ord(substr($value, $i));
}
return $hash;
}
Upvotes: 2
Reputation: 252
It may have to do with whether or not the operating system is 32-bit or 64-bit. If you shift $hash too far left, you could end up with an overflow error, and wrap around to negative numbers.
The solution depends on your needs. If all you need is a positive integer, and it doesn't matter if the values are consistent across operating systems, just wrap the returned value with abs() to make sure the result is positive.
If you need the result to always be consistent, you'll probably need to truncate the result to be stored in 32 bits at most. Using something like:
$32bitresult = rphash($value) & 0xFFFFFFFF;
should work.
NOTE: You may want to add a check to see if the result of rphash is negative before AND-ing the two.
Take a look at this similar problem/answer:
Force PHP integer overflow
I haven't been able to test the code out, but maybe it'll help you on your way at least.
Upvotes: 1