你能将php crypt()的输出转换为有效的MD5吗?

我有一些使用 PHP function crypt()加密的字符串.

输出看起来像这样:

$1$Vf/.4.1.$CgCo33ebiHVuFhpwS.kMI0
$1$84..vD4.$Ps1PdaLWRoaiWDkcfjLyV1
$1$or1.RY4.$v3xo04v1yfB7JxDj1sC/J/

虽然我相信crypt()正在使用MD5算法,但输出不是有效的MD5哈希值.

有没有办法将生成的哈希值转换为有效的MD5哈希值(16字节十六进制值)?

更新:

感谢回复到目前为止的答案.我很确定使用的crypt函数是使用某种MD5算法.我要做的是将我拥有的输出转换为MD5哈希,如下所示:

9e107d9d372bb6826bd81d3542a419d6  
e4d909c290d0fb1ca068ffaddf22cbd0  
d41d8cd98f00b204e9800998ecf8427e

(摘自Wikipedia)

有没有办法从我有的哈希转换成上面的哈希?

好吧,也许这个答案迟了一年,但我会试一试.在你自己的回答中,你注意到crypt()正在使用FreeBSD MD5,它在运行哈希之前也对salt进行了一些有趣的转换,所以我将要给你的结果永远不会与调用md5()的结果.也就是说,您看到的输出与您习惯使用的格式之间的唯一区别是您看到的输出编码如下
$1$       # this indicates that it is MD5
Vf/.4.1.   # these eight characters are the significant portion of the salt
$         # this character is technically part of the salt,but it is ignored
CgCo33eb   # the last 22 characters are the actual hash
iHVuFhpw   # they are base64 encoded (to be printable) using crypt's alphabet
S.kMI0     # floor(22 * 6 / 8) = 16 (the length in bytes of a raw MD5 hash)

据我所知,crypt使用的字母表如下所示:

./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

因此,考虑到所有这些,下面是如何将22个字符的crypt-base64哈希转换为32个字符的base16(十六进制)哈希:

首先,您需要将base64(使用自定义字母)转换为原始的16字节MD5哈希.

define('CRYPT_ALPHA','./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
/**
 * Decodes a base64 string based on the alphabet set in constant CRYPT_ALPHA
 * Uses string functions rather than binary transformations,because said
 * transformations aren't really much faster in PHP
 * @params string $str  The string to decode
 * @return string       The raw output,which may include unprintable characters
 */
function base64_decode_ex($str) {
    // set up the array to Feed numerical data using characters as keys
    $alpha = array_flip(str_split(CRYPT_ALPHA));
    // split the input into single-character (6 bit) chunks
    $bitArray = str_split($str);
    $decodedStr = '';
    foreach ($bitArray as &$bits) {
        if ($bits == '$') { // $indicates the end of the string,to stop processing here
            break;
        }
        if (!isset($alpha[$bits])) { // if we encounter a character not in the alphabet
            return false;            // then break execution,the string is invalid
        }
        // decbin will only return significant digits,so use sprintf to pad to 6 bits
        $decodedStr .= sprintf('%06s',decbin($alpha[$bits]));
    }
    // there can be up to 6 unused bits at the end of a string,so discard them
    $decodedStr = substr($decodedStr,strlen($decodedStr) - (strlen($decodedStr) % 8));
    $byteArray = str_split($decodedStr,8);
    foreach ($byteArray as &$byte) {
        $byte = chr(bindec($byte));
    }
    return join($byteArray);
}

现在您已经获得了原始数据,您需要一种方法将其转换为您期望的base-16格式,这可能会更容易.

/**
 * Takes an input in base 256 and encodes it to base 16 using the Hex alphabet
 * This function will not be commented.  For more info:
 * @see http://PHP.net/str-split
 * @see http://PHP.net/sprintf
 *
 * @param string $str   The value to convert
 * @return string       The base 16 rendering
 */
function base16_encode($str) {
    $byteArray = str_split($str);
    foreach ($byteArray as &$byte) {
        $byte = sprintf('%02x',ord($byte));
    }
    return join($byteArray);
}

最后,由于crypt的输出包含了大量的数据,我们不需要(事实上,不能使用)这个过程,一个短而甜的功能,不仅将这两个结合在一起,而且允许直接输入输出来自地穴

/**
 * Takes a 22 byte crypt-base-64 hash and converts it to base 16
 * If the input is longer than 22 chars (e.g.,the entire output of crypt()),* then this function will strip all but the last 22.  Fails if under 22 chars
 *
 * @param string $hash  The hash to convert
 * @param string        The equivalent base16 hash (therefore a number)
 */
function md5_b64tob16($hash) {
    if (strlen($hash) < 22) {
        return false;
    }
    if (strlen($hash) > 22) {
        $hash = substr($hash,-22);
    }
    return base16_encode(base64_decode_ex($hash));
}

给定这些函数,您的三个示例的base16表示形式为:

3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154

当然,重要的是要记住它们总是有效的,只是格式不同.

相关文章

Hessian开源的远程通讯,采用二进制 RPC的协议,基于 HTTP 传输。可以实现PHP调用Java,Python,C#等多语...
初识Mongodb的一些总结,在Mac Os X下真实搭建mongodb环境,以及分享个Mongodb管理工具,学习期间一些总结...
边看边操作,这样才能记得牢,实践是检验真理的唯一标准.光看不练假把式,光练不看傻把式,边看边练真把式....
在php中,结果输出一共有两种方式:echo和print,下面将对两种方式做一个比较。 echo与print的区别: (...
在安装好wampServer后,一直没有使用phpMyAdmin,今天用了一下,phpMyAdmin显示错误:The mbstring exte...
变量是用于存储数据的容器,与代数相似,可以给变量赋予某个确定的值(例如:$x=3)或者是赋予其它的变...