【发布时间】:2011-10-18 17:32:43
【问题描述】:
我在 PHP 方面非常缺乏经验,所以这对你们中的一些人来说可能很明显,但是如果我在 PHP 中调用 md5($mystring,true) 它会说它返回一个“长度为 16 的原始二进制格式”。那是什么?它是一个数组吗?什么数组?如何读取该返回值的各个位和字节?
我在网上找到的所有例子都没有直接使用 base64_encode() 或其他东西。例如,我只是希望能够检查第五位或第三个字节。
【问题讨论】:
我在 PHP 方面非常缺乏经验,所以这对你们中的一些人来说可能很明显,但是如果我在 PHP 中调用 md5($mystring,true) 它会说它返回一个“长度为 16 的原始二进制格式”。那是什么?它是一个数组吗?什么数组?如何读取该返回值的各个位和字节?
我在网上找到的所有例子都没有直接使用 base64_encode() 或其他东西。例如,我只是希望能够检查第五位或第三个字节。
【问题讨论】:
var_dump(md5("string", TRUE));
“原始二进制格式”表示字符串(因为字符串在 PHP 中是二进制安全的):
string(16) "�\����= �(��^{!"
如果您想从中读取一个字节,请使用$string[5] 偏移量语法。或者从第五个字节中提取一个位,例如:
$bit4_from_5th_byte = ord($result[5]) & (1 << 4);
【讨论】:
它将它作为“字符串”返回,每个字符都是输出的一个字节。您可能会考虑使用不带第二个参数的 md5() 的十六进制输出,并使用 intval() 将其子字符串转换为数字,并将 16 作为基本参数。像这样:
$hash = md5($raw);
$byte = intval(substr($hash, 0, 2), 16);
【讨论】:
MD5 哈希是一个 128 位的数字,例如16 字节的原始二进制数据。为了便于阅读,PHP 的 md5() 函数默认将其输出为人类可读的字符串,其中 16 个二进制字节被转换为 32 个字符的字母数字字符串。
当您为 MD5 指定第二个 true 参数时,您是在告诉 PHP 返回该原始 128 位数字而不是人类可读的版本。
【讨论】:
get converted into a 32 character 确实是get converted into a 16 character,因为它被转换为十六进制。
MD5 的 RAW 输出是哈希的纯二进制字符串。您无法将其打印到屏幕上,因为它不是编码为实际的 ASCII 字符而是二进制数。这仅在您需要以二进制格式存储或传输哈希时才有用。
【讨论】:
获取单个位:
$md5 = md5( "b", true );
$l = strlen( $md5 );
$bits = "";
for( $i = 0; $i < $l; ++$i ) {
$num = ord( $md5[$i] );
for( $j = 7; $j >= 0; --$j ) {
$bits .= ( $num & ( 1 << $j ) ) ? "1" : "0";
}
}
echo $bits."\n";
//10010010111010110101111111111110111001101010111000101111111011000011101011010111000111000111011101110101001100010101011110001111
echo asciibin2hex( $bits ) == md5("b"); // true
所以我们逐字节进行,由于它是字符串形式,我们需要将其转换为ord()的ASCII数字。现在逐位检查字节,查看哪些已打开,哪些已关闭并连接到位串。转到下一个字节并冲洗并重复,直到读取所有 128 位。
在第三个字节中读取第三位(从左到右):
ord( $md5[2] ) & ( 1 << ( 8 - 3 ) )
如果该位打开则返回 1,否则返回 0
【讨论】: