php将文字转换成md5,你能将php crypt()的输出转换为有效的MD5吗?

这篇博客详细介绍了如何将crypt()函数生成的基于FreeBSD MD5的base64哈希转换为标准的base16(十六进制)哈希。文章提供了PHP代码实现,包括base64解码和base16编码的过程,并指出这种转换对于理解哈希格式的重要性。
摘要由CSDN通过智能技术生成

好吧,也许这个答案迟了一年,但我会试一试.在你自己的回答中,你注意到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, 0, 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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值