gpt4 book ai didi

php - PHP unpack() 的意外行为

转载 作者:可可西里 更新时间:2023-11-01 13:21:31 26 4
gpt4 key购买 nike

测试

$x = sprintf( "foo\x00bar\x00baz" );
$y = unpack( 'afoo/abar/abaz' , $x );
print_r( $y );
$x = sprintf( "foo\x00bar\x00baz" );
$y = unpack( 'a*foo/a*bar/a*baz' , $x );
print_r( $y );

结果

Array(    [foo] => f    [bar] => o    [baz] => o)
Array(    [foo] => foobarbaz    [bar] =>     [baz] => )

请注意,NULL 字节始终存在,您可以使用 hexdump 检查它。

预期结果

Array(    [foo] => foo    [bar] => bar    [baz] => baz)

注意事项

我知道我可以使用 explode 来获得类似的结果。我不是在问一个替代方案,我只是想了解 a 格式字符(如文档所说的“NUL 填充字符串”)背后的逻辑。

“NULL”值在哪里涉及所有这一切?

最佳答案

原始答案

““NULL”值在哪里涉及这一切?”

无处可去。

我很确定 PHP pack()/unpack() 的文档需要更新。基本上,无论您在哪里看到它指的是 NULL 终止字符串,文档都是从代码的 Perl 版本中获取的,并不反射(reflect) PHP 中发生的事情。

基本上 Perl 有 C 风格的字符串,可以用 null 终止,让您知道字符串的结尾在哪里。在 PHP 中没有 NULL 字符的概念。例如

$test1 = "Test".NULL."ing";
$test2 = "Testing";

if(strcmp($test1, $test2) == 0){
echo "The strings are the same";
}
else{
echo "They are different.";
}

将打印“字符串相同”。

顺便说一句: “foo\x00bar\x00baz”

可能并没有按照您的想法行事。它不会在 foo + bar 和 bar + baz 之间的字符串中放置“NULL”字符,因为没有 NULL 字符。相反,它放置了字符“0”,它恰好不会在大多数字符集中打印出来,但作为字符没有特殊含义。

我知道你提到过使用 explode 而不是 unpack 但如果你知道字符串长度那么你可以使用:

unpack( 'a3foo/a3bar/a3baz' , $binarydata);

为清楚起见添加

赛勒斯写道:

With "NULL byte" I mean the byte with the value 0:

我不确定你从哪里得到字符串“foo\x00bar\x00baz”但是:

i) 它必须来自支持用零表示的 NULL 字符的语言。 PHP 不支持 NULL 字符,如果您调用 包装(“A*A*A*”、“foo”、“bar”、“baz”);它不会生成其中包含零的字符串。

ii) PHP 版本的 unpack 不支持 NULL 字符(因为 PHP 不支持 NULL 字符)并将十六进制值为 0 的字符视为另一个字符。例如

function strToHex($string){
$hex='';
for ($i=0; $i < strlen($string); $i++)
{
$hex .= dechex(ord($string[$i]));
}
return $hex;
}

$binarydata = "foo\x00bar\x00baz";

echo "binarydata is ";

var_dump($binarydata);
$y = unpack( 'a3foo/a3bar/a3baz' , $binarydata);
var_dump( $y );

echo strToHex($y['foo'])."\r\n";
echo strToHex($y['bar'])."\r\n";
echo strToHex($y['baz'])."\r\n";

将输出:

binarydata is string(11) "foobarbaz"
array(3) {
["foo"]=>
string(3) "foo"
["bar"]=>
string(3) "ba"
["baz"]=>
string(3) "rb"
}
666f6f
06261
72062

即它提取前三个字符,它们的值为 0x66、0x6f、0x6f。然后它提取接下来的三个字符,即 0x0、0x62、0x61。最后它提取值 0x72、0x0、0x62。

关于php - PHP unpack() 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11631437/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com