Best way to mask integer as 32-bit? - php

I am running a 64-bit installation of PHP, and from my understanding there is not way to specifically declare a variable as a 32 bit unsigned int.
Using this code as an example:
$test1 = 0x5BE0CD19;
$test2 = 0x3587272B;
$test3 = 0x1F85C98C;
$test4 = 0x428A2F98;
$test5 = 0x61626380;
$test6 = ($test1 + $test2 + $test3 + $test4 + $test5);
Gives me the result 0x154da50e8
Currently I do the following operations to mask variables as 32 bit:
$test6 &= (1 << 32) - 1;
I get my desired result of: 0x54da50e8
For performance reasons, I was wondering, is there a better way to do this without having to use &= (1 << 32) - 1; for every variable in the event of an overflow?
It gets quite cluttered constantly adding the mask to each variable on a per-calculation basis.
Thanks

Related

Move Function - Pascal to PHP

Good day,
Trust all is well.
I want to duplicate the Move function from Pascal to PHP.
Here is what I have In Pascal:
function Encode(const S: AnsiString): AnsiString;
const
Map: array [0 .. 63] of Char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'abcdefghijklmnopqrstuvwxyz0123456789+/';
var
i: LongInt;
begin
i := 0; ;
Move(S[1], i, Length(S));
Result := Map[i mod 64] + Map[(i shr 6) mod 64];
end;
Here is what I have in PHP:
private function Encode($pass)
{
$map = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/');
$i = 0;
$this->MoveFunction($pass[0], $i, mb_strlen($pass));
$result = $map[$i % 63] . $map[($i >> 6) % 64];
return $result;
}
Now I now know that the Move function is used to copy a section of memory from one place to another, just not sure where to begin and how it would be done. I could not replicate the results from Pascal in PHP. I have tried sub strings ens. to no avail.
The "$this->MoveFunction" is the function that I will need to write in order to duplicate the functionality of the Move function from pascal. I need to use the same outcome of the Move from pascal in order to use the same encryption field from a similar DB.
I think this is an easy way to test in Pascal:
var
A: array[1..4] of Char;
B: Integer;
begin
A[1] := 'W';
A[2] := 'H';
A[3] := 'A';
A[4] := 'T';
B := 5;
Move(A, B, SizeOf(B));
showmessage(B.ToString()); // 4718679
Any help would be greatly appreciated.
Thank you in advance.
Pascal code moves some AnsiChars into 32-bit Int variable. Note that the first char becomes the least significant byte of integer (due to byte order), and result is just equal to
Result := Map[Byte(S[1]) mod 64];
so Move is not needed at all, all other symbols of string aren't involved in work.
If you can cast the first symbol of $pass as byte/int variable in PHP - work is done.
P.S. I see ord() function, so code might look like this:
(I also changed % to bitwise &)
private function Encode($pass)
{
$map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$i = ord($pass[0]);
$result = $map[$i & 63];
return $result;
}
For shr:
Result := Map[i mod 64] + Map[(i shr 6) mod 64]; =>
$a = ord($pass[0]) & 63;
$b = ord($pass[0]) >> 6; //two ms bits
$b = $b & 3; //to clear ms bits
$c = ord($pass[1]) & 15; //four ls bits
$d = $b | ($c << 2); //combine them
$result = $map[$a].$map[$d];

How to conver bin data to int16 in php

I have this code in Qt c++
const unsigned char *packed = reinterpret_cast<const unsigned char*>(data.constData());
res.type = static_cast<int>(packed[0]);
res.period = static_cast<int>(packed[1]);
res.rate = static_cast<qint16>(packed[2] | (packed[3] << 8)) / 100.;
res.edge = static_cast<qint16>(packed[4] | (packed[5] << 8)) / 100.;
return res;
How to convert it from c++ to php
I try this:
$a = unpack ("C*", $data);
$eventList = [];
for ($i=0; $i < $a[1]; $i++)
{
$event = array ();
$index = $i * 6 + 2;
$event["type"] = $a[$index];
$event["period"] = $a[$index+1];
$event["rate"] = ($a[$index+2] | ($a[$index+3] << 8)) / 100;
$event["edge"] = ($a[$index+4] | ($a[$index+5] << 8)) / 100;
}
Edge conver wrong
Very big value.
[edge] => 650.86
must be -4.5
Type, period and rate is good;
Help me please
Don't know the exact answer but some of possible ways to solve the problem:
Check $a[$index+4] and $a[$index+5] value by using var_dump to get its value and type:
var_dump($a[$index+4]);
var_dump($a[$index+5]);
is the data type and its value as expected? Probably good idea is to check as above all data before/after calculation to exactly know what you are dealing with.
Double check your conversion type, perhaps you should't use C* but other, perhaps S or s?
conversion types
If you need type conversion in php you can check how it is done here: Type Juggling and Casting
Note that in PHP you can use a string with ASCII digit that can be treated as digit for calculations:
$foo = 5 * "10 Little Piggies"; // $foo is integer (50)
Which is something you probably don't want.
If you expect negative value but you get positive you have problem because your'e not setting MSB by shifting bits:
The MSB can also correspond to the sign bit of a signed binary number
read-wiki
in case packed[5] should be negative but it isn't
If this not helps then provide data sample and expected values for Edge, Type, period and rate.

Operator precedence depends upon lanaguage or independent

I have seen a question on stack over flow.
What's happening with this expression? b = a + (a = a + 5)
It shows the value of b will be 15. But when i run this code on Php, value of b is 20.
Why there is difference of output in php and C#
It's happens because PHP and C# differently used memory for save variables.
Read How PHP manages variables.
So PHP not duplicated zval memory for variable "$a" and value of $a changed when ($a = $a +5) has been completed so we have that
$a = 5;
echo $a + ($a = $a + 5); //20
and C# has duplicated memory for a variables read answer What's happening with this expression? b = a + (a = a + 5).

a = (a + b) - (b = a); C++ vs php

I've been looking around and found formula: a = (a + b) - (b = a) it is supposed to swap two variables (or objects in some cases). However I tested it with C++ and php, these gave me different result.
php:
$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
echo $a, " ", $b;
This prints 20 10
C++
int a = 10;
int b = 20;
a = (a + b) - (b = a);
std::cout << a << " " << b;
This prints 10 10
Code looks the same but outputs are different, I've been thinking about two reasons:
C++ code is compiling and php is interpreting.
This formula is useless because it leads to undefined behavior.
Can somebody explains, why C++ and php output differs in this situation?
I'm not sure what the rules are in PHP, but in C++, the order of individual sub-expressions isn't strictly defined, or as the technical term is, it is "unspecified" - in other words, the compiler is allowed to calculate b = a before or after it does a + b. As long as it does a + b and b = a before the subtraction. The use of "unspecified" behaviour allows the compiler to produce more efficient code in some cases, or simply that it's possible to build a compiler for some architectures.
It also means that if you have an expression that "recalculates" a value within the expression itself, and also using it elsewhere in the expression, you get unedefined behaviour (UB for short). UB means just that, the behaviour is not defined - almost anything could happen, including what you are seeing and many other alternatives (e.g. the compiler is allowed to produce 42 as a result as well, even if logic says the answer wouldn't be 42 in this case [it's the wrong question for that!]).
I would also suggest that if you want to swap two values, in PHP:
$t = $a;
$a = $b;
$b = $t;
and in C++:
#include <algorithm>
std::swap(a, b);
or if you insist on writing your own:
int t = a;
a = b;
b = t;
Trying to be clever and perform it "without temporary variable" is almost certainly going to make it slower than the use of a temporary - certainly in a compile language like C++ - in a interpreted language like PHP, creating a new variable may add a bit of extra overhead, but it's unlikely to be that big, compared to the extra effort in the logic required.
C++ code is completely broken because of undefined behavior. (read and write b in one sequence point).
For PHP:
$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
//executes like thus
$a = (30) - ($b = $a);
$a = (30) - ($b = $a = 10); //new $a still not computed, using older $a
$a = (30) - (10);
$a = 20;
//then, $a=20 and $b = 10
This is totally related to Operator Precedence, this might be same in C or might not, it depends on precedence if unexpected behavior not occur.

Getting different results in PHP and JS when bit shifting

I'm getting some odd results where 2 identical functions (one in PHP and one in javascript) are returning different results.
The input for both of these lines of code is identical:
a = 4653896912;
b = 13;
I have double checked the variable types and both variables are numbers in JS and integers in PHP.
The line of code for PHP is this:
$a = $a >> $b;
For Javascript it's this:
a = a >> b;
You'd expect a to have the same value after both, but I'm getting the following:
PHP: $a = 568102
JS: a = 43814
Which has completely baffled me at this point.
Turns out this is definitely an issue of PHP using 64 bit integers and JS only using 32 bit. The problem I face now is that I need to get PHP to use 32-bit integers for these calculations. I found a function someone else wrote that looks like it should work, but it doesn't seem to be changing the output at all for me.
private static function toInt32(&$x) {
$z = hexdec(80000000);
$y = (int) $x;
if($y ==- $z && $x <- $z){
$y = (int) ((-1) * $x);
$y = (-1) * $y;
}
$x = $y;
}
The below code demonstrates masking the upper 32 bits of the number to retrieve only the lower 32 bits to use in your calculations. 4294967295 is 2^32 - 1. I think that if you mask all values that could be greater than 32 bits in this manner, then you can get the same results from your php and javascript.
<?php
$php_a = 4653896912;
$php_b = 13;
//convert $php_a into a 32 bit val
$php_a = $php_a & 4294967295;
$a = $php_a >> $php_b;
echo "PHP: \$a = $a <br />";
?>
<script type="text/javascript">
var a = 4653896912;
var b = 13;
var a = a >> b;
alert('Javascript A value is ' + a);
</script>
4653896912 is more than 32 bits.. unpredictable results are likely. I get $a = 43814 for PHP, but that is actually 358929617 >> 13, so in all likelihood PHP is doing 64 bit operations but JavaScript is only 32 bit.
I believe it's because you're a is above the limit of a 32-bit signed integer for [PHP][1].
The highest value possible is about 2 million, and a is over 4 billion.
When you're rolling over because of space limitations, results can be unpredictable (or at least, very difficult to figure out).
If your server is on a 64-bit version of PHP then it'll max out much higher than than, but javascript is limited by what the end-user is running.
You can read up on PHP on their integers page.

Categories