read_big_endian()
云策文档标注
概述
read_big_endian() 函数用于以大端字节序读取无符号整数,支持不同字节长度的输入。它基于 PHP 的 unpack 函数实现,并处理 32 位系统的潜在溢出问题。
关键要点
- 函数读取大端字节序的无符号整数,参数包括输入字符串 $input 和字节数 $num_bytes。
- 根据 $num_bytes 的值(1、2、3 或 4),使用不同的 unpack 格式(如 'C'、'n'、'N')进行解析。
- 对于 3 字节输入,手动计算值;对于 4 字节输入,注意在 32 位系统上可能溢出超过 2^31。
代码示例
function read_big_endian( $input, $num_bytes ) {
if ( $num_bytes == 1 ) {
return unpack( 'C', $input ) [1];
} else if ( $num_bytes == 2 ) {
return unpack( 'n', $input ) [1];
} else if ( $num_bytes == 3 ) {
$bytes = unpack( 'C3', $input );
return ( $bytes[1] << 16 ) | ( $bytes[2] << 8 ) | $bytes[3];
} else if ( $num_bytes == 4 ) {
// 注意:在 32 位系统上,可能返回有符号整数,如果值 > 2^31。
// 参见 https://www.php.net/manual/en/function.unpack.php#106041
return unpack( 'N', $input ) [1];
}
}注意事项
- 输入字符串 $input 必须至少为 $num_bytes 长度,否则可能导致错误。
- 当 $num_bytes 为 4 时,在 32 位 PHP 系统上,如果值超过 2^31,unpack('N') 可能返回有符号整数,需注意潜在溢出问题。
原文内容
Reads an unsigned integer with most significant bits first.
Parameters
-
string $input Must be at least $num_bytes-long.
$num_bytesintrequired-
Number of parsed bytes.
Source
function read_big_endian( $input, $num_bytes ) {
if ( $num_bytes == 1 ) {
return unpack( 'C', $input ) [1];
} else if ( $num_bytes == 2 ) {
return unpack( 'n', $input ) [1];
} else if ( $num_bytes == 3 ) {
$bytes = unpack( 'C3', $input );
return ( $bytes[1] << 16 ) | ( $bytes[2] << 8 ) | $bytes[3];
} else { // $num_bytes is 4
// This might fail to read unsigned values >= 2^31 on 32-bit systems.
// See https://www.php.net/manual/en/function.unpack.php#106041
return unpack( 'N', $input ) [1];
}
}