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!

Jsowa
  • 9,104
  • 5
  • 56
  • 60
Fabio978
  • 21
  • 3
  • I think the ` | 0` part doesn't translate directly into PHP (I think). – Nigel Ren Apr 08 '20 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. – Fabio978 Apr 08 '20 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. – Triby Apr 08 '20 at 16:28
  • Cool! Thanks for the tip Triby! – Fabio978 Apr 08 '20 at 16:35

1 Answers1

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?

Jsowa
  • 9,104
  • 5
  • 56
  • 60
  • 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. – Fabio978 Apr 08 '20 at 16:37