Tamam, belki bu cevap bir yıl geç, ama ben bunu bir deneyeyim. Kendi cevap olarak, crypt()
ayrıca karma çalıştırmadan önce tuz bazı ilginç dönüştürmeleri yapar FreeBSD MD5 kullanarak, unutmayın, bu yüzden seni asla oldukça vermek üzereyim ne sonuç Bir çağrı sonuçları ile maç md5()
. O dedi, görüyoruz çıktı ve sizin için kullanılan biçimi arasındaki tek fark aşağıdaki gibi görüyoruz çıktı kodlanmış olmasıdır
$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)
Bildiğim kadarıyla, crypt tarafından kullanılan alfabe, bu gibi görünüyor:
./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Yani, akılda tüm bu ile, burada 32 karakter base16 (onaltılık) karma içine 22 karakter crypt-base64 hash dönüştürebilirsiniz nasıl:
İlk olarak, bir çiğ 16-bayt MD5 hash içine (özel alfabe ile) base64 dönüştürmek için bir şey gerekir.
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);
}
Şimdi ham veri var ki, daha kolay olamazdı siz bekliyorsanız taban-16 formatında dönüştürmek için bir yöntem gerekir.
/**
* 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);
}
Nihayet, mahzenin çıkış verilerinin çok ihtiyacımız yoktur (ve, aslında, kullanamazsınız) Bu işlem için, kısa ve tatlı bir işlevi bu ikisini bağlamak için değil, ancak çıkış doğrudan giriş için izin içerdiğinden mezarından.
/**
* 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));
}
Bu işlevleri göz önüne alındığında, üç örnekten base16 temsilidir:
3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154
Tabii ki, her zaman sadece farklı biçimlendirilmiş, geçerli olduğunu hatırlamak önemlidir.