Alexander Fedoseev
Alexander Fedoseev

Reputation: 101

Different results between Ruby Digest::MD5.base64digest and PHP base64_encode

I didn't work with ruby ever, only with php. And I need help.

I have ruby code which encode string like that:

str = '123';
arr = str.bytes
p Digest::MD5.base64digest(arr.pack('C*')) # ICy5YqxZB1uWSwcVLSNLcA==

I need to do the same in php, and get the the same result. My example

$str = '123';
$bytes = unpack('C*', $str);
$pack = pack('C*', implode(', ', $bytes));
echo base64_encode(md5($pack)); // YzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWI=

Why the results are different. Thanks for help.

Upvotes: 3

Views: 810

Answers (1)

Lawrence Cherone
Lawrence Cherone

Reputation: 46620

As its unpacking and then repacking the bytes it's not needed, but ill keep the code as-is.

In PHP pack requires each array argument to be passed, so you need to re-pack each argument in a loop.

<?php
$str = 123;
$bytes = unpack('C*', $str);
$pack = null;
foreach ($bytes as $arg) $pack .= pack('C*', $arg);

Or in PHP > 5.6 you can use inline argument unpacking. ...

$str = 123;
$bytes = unpack('C*', $str);
$pack = pack('C*', ...$bytes);

Then the last issue is because rubys base64digest maintains the digest state, you also need to use md5's second param raw_output to do the same.

If the optional raw_output is set to TRUE, then the md5 digest is instead returned in raw binary format with a length of 16.

$str = 123;
echo base64_encode(md5($str, true));

So your finished ported code would look like:

$str = 123;
$bytes = unpack('C*', $str);
$pack = pack('C*', ...$bytes);
echo base64_encode(md5($pack, true)); // ICy5YqxZB1uWSwcVLSNLcA==

Or just.

<?php
$str = 123;
echo base64_encode(md5($str, true)); // ICy5YqxZB1uWSwcVLSNLcA==

Upvotes: 1

Related Questions