0

I'm trying to convert a pretty simple function from NodeJs to PHP. I think I found out how to convert 80% of it, but I am stuck around bitwise operators.

This is the original NodeJs script:

function convert(encodedString) {
  let bytes = new Buffer.from(encodedString, 'base64')
  let code = bytes[bytes.length - 1]
  code ^= 91

  for (let i = 0; i < bytes.length - 1; ++i) {
    bytes[i] = ((bytes[i] ^ (code << (i % 5))) | 0)
  }

  return bytes
}

And this is the converted PHP version

function convert($encoded)
{
    $bytes = unpack('C*', base64_decode($encoded));
    $code = $bytes[count($bytes)];
    $code ^= 91;

    for($i = 0; $i < count($bytes) - 1; ++$i) {
        $bytes[$i + 1] = (($bytes[$i + 1] ^ ($code << ($i % 5))) | 0);
    }  

    return $bytes;
}

This somehow works until the bitwise part. I get the correct result for the first element of the array, but all the consequent values are wrong. I also had to adapt indexing because with the unpack method i get an base-1 index array.

If I loop each array's value before the conversion, I have the same result on both scripts, so I think is correct until that.

I was able to reproduce the issue on NodeJs, if for example I define a normal array (with same values) instead using Buffer.

I don't really know how to reproduce the same behaviour in PHP.

Any help is appreciated!

4
  • I think the ` | 0` part doesn't translate directly into PHP (I think). Commented Apr 8, 2020 at 15:49
  • Thanks Nigel. The point is that if I for example edit the NodeJS code using b[i] = instead of using bytes[i] = (so using a normal array), I have the same exact behaviour as on PHP. I don't know if the difference is the Buffer array or what else. Commented Apr 8, 2020 at 16:07
  • 1
    Is $bytes 1-based array instead of 0-based? Force it to be 0-based with $bytes = array_merge(unpack('C*', base64_decode($encoded))); then you can deal with indexes without changing $i and focus on bitwise operators. Commented Apr 8, 2020 at 16:28
  • Cool! Thanks for the tip Triby! Commented Apr 8, 2020 at 16:35

1 Answer 1

3

Bitwise operators in Javascript and PHP handle calucations differently.

Example:

Javascript:

1085 << 24 = 1023410176

PHP:

1085 << 24 = 18203279360

Bitwise operations PHP and JS different

You should write your own function for bitwise operators in PHP. What is JavaScript's highest integer value that a number can go to without losing precision?

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Tajniak. If that's the reason, I can't understand why if I use a normal array in JS I have the exact same result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.