简体   繁体   中英

PHP MD5 equivalent to Java

I need a PHP equivalent for Java's MD5 functionality which takes a byte array and return the hash as a 16 byte array back. I'm not need an Java equivalent for the PHP's md5 function. The problem is that the PHP's md5 function takes only strings, not byte arrays.

Heres is the expected result in Java:

// input byte array
// for short: 123456
final byte[] data = new byte[] { (byte) 0x12, (byte) 0x34, (byte) 0x56 };

// expected 16 hash bytes
// for short: ae1fa6209a246b8b2f2cd2d21be8f2e1
final byte[] expectedHash = new byte[] {
        (byte) 0xae, (byte) 0x1f, (byte) 0xa6, (byte) 0x20,
        (byte) 0x9a, (byte) 0x24, (byte) 0x6b, (byte) 0x8b,
        (byte) 0x2f, (byte) 0x2c, (byte) 0xd2, (byte) 0xd2,
        (byte) 0x1b, (byte) 0xe8, (byte) 0xf2, (byte) 0xe1 };

My try in PHP is:

<?php
// input byte array
$data = array(0x12, 0x34, 0x56);

// pack data in a string, becouse md5 can only
// compute a hash for a string
$dataString = pack('C*', $data); // is it the right way?
var_dump($dataString);

// compute the hash and get a string back
$hash = md5($dataString, true);

// expected 16 hash bytes
// for short: ae1fa6209a246b8b2f2cd2d21be8f2e1
$expected = array(
    0xae, 0x1f, 0xa6, 0x20,
    0x9a, 0x24, 0x6b, 0x8b,
    0x2f, 0x2c, 0xd2, 0xd2,
    0x1b, 0xe8, 0xf2, 0xe1);
var_dump($expected);

// convert the string back to a byte array
$actual = unpack('C*', $hash); // is it the right way?
var_dump($actual);

assert($expected == $actual);
?>

$dataString has the length of 0. So the first error must be in pack . But I don't know how to pack an arbitrary byte array into a string. Can you give me the right format argument for that?

I've got it :)

<?php
function javaMd5($data) {
    assert(is_array($data));

    $dataString = byteArrayToString($data);

    $hashString = md5($dataString, true);
    assert(strlen($hashString) == 16);

    $hash = stringToByteArray($hashString);

    assert(count($hash) == 16);
    return $hash;
}

function stringToByteArray($s) {
    assert(is_string($s));

    $result = array_fill(0, strlen($s), 0);
    for ($i = 0; $i < strlen($s); $i++) {
        $result[$i] = ord($s[$i]);
    }
    return $result;
}

function byteArrayToString($b) {
    assert(is_array($b));

    $asciiString = '';
    for ($i = 0; $i < count($b); $i++) {
        assert($b[$i] >= 0 && $b[$i] <= 255);
        $asciiString .= chr($b[$i]);
    }

    $utf8String = utf8_encode($asciiString);

    return $utf8String;
}

$data = array(0x12, 0x34, 0x56);

$expected = array(
    0xae, 0x1f, 0xa6, 0x20,
    0x9a, 0x24, 0x6b, 0x8b,
    0x2f, 0x2c, 0xd2, 0xd2,
    0x1b, 0xe8, 0xf2, 0xe1);

$actual = javaMd5($data);

assert($expected == $actual);
?>

I'am not sure about string encoding but it works. I don't have an explinations for that PHP uses a implicit xyz-encoded string instead of an explizit byte array like Java does. The manuel doesn't say everithing about char encoding. Thats might be the reason for that there are so many questions about how to calculate the md5 of a string aquivalent to PHP in the language XYZ.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM