右移不按预期工作

时间:2014-01-24 18:51:18

标签: php

我需要做些什么来抽取我从其他来源获得的一些数据。

我得到的数据在二进制文件中看起来像这样:

01100011 00000000 00000000 00000000

这是十进制数99的小端编码。

我想用这个值掩盖(按位和):

01000000 00000000 00000000 00000000

然后一直向右移动(30个地方)。

然而,当我尝试右移时,我得到:

00000000 00000000 00000000 00110000

我无法弄清楚原因。

以下是代码:

function binrep($bin,$len=32) {
    return implode(' ',str_split(str_pad(decbin(hexdec(bin2hex($bin))),$len,'0',STR_PAD_LEFT),8));
}


function mask($data,$pos,$len=1,$size=32) {
    $bits = (1<<$len)-1;
    $shift = $size - $pos - $len;
    $mask = pack('N',$bits << $shift);
    echo binrep($data)."\n".binrep($mask)."\n".binrep(($data&$mask)>>$shift);
    return ($data & $mask) >> $shift;
}

mask(pack('V',99),1);

这个价值来自哪里?为什么不是结果

00000000 00000000 00000000 00000001

2 个答案:

答案 0 :(得分:1)

这是类型不匹配。由于($data & $mask)求值为字符串,因此php会隐式将$shift的类型更改为字符串以执行操作。根据php文档,这意味着>>运算符正在使用ascii值来进行计算。我将此函数添加到您的代码中:

function decrep($bin)
{
return hexdec(bin2hex($bin));
}

然后使用此函数binrep(pack('N',((decrep($data) & decrep($mask)) >> $shift)))向右移动,这会得到正确的结果。

答案 1 :(得分:0)

任何需要从32位int中提取随机位的人的完整解决方案:

function decrep($bin) {
    return hexdec(bin2hex($bin));
}

function binrep($bin,$len=32) {
    return implode(' ',str_split(str_pad(decbin(hexdec(bin2hex($bin))),$len,'0',STR_PAD_LEFT),8));
}

function extractBits($data,$pos,$len=1,$size=32) {
    $bits = (1<<$len)-1;
    $shift = $size - $pos - $len;
    $mask = pack('N',$bits << $shift);
    return (decrep($data) & decrep($mask)) >> $shift;
}

用法:

$result = extractBits($data,1,2); // pulls out the 2nd and 3rd to left bit, returns number in range 0-3