从Hex中获取PHP中最不重要的位

时间:2011-05-30 18:37:18

标签: php bit-manipulation

我有一个带十六进制代码的文件,我需要从文件中的每个字节获取所有最低有效位,连接它们,将它们分成8组,然后将字节转换为ASCII。我的问题是从每个字节中提取LSB。

hex文件看起来像这样(但更长):

58 00 00 1F 58 00 00 00 00 00 00 00 00 00 00 1C 22 23 1F 26 25 1E 2C 26 20 31 2B 22 38 2F 26 42 36 25 47 37 24 49 39 22

我的代码如下所示:

<?php
// Read file, remove spaces
$file = implode('', explode(' ', file_get_contents('vogel.hex')));

// Save LSB
$bits = array();
for ($i = 1; $i < strlen($file); ++$i)
{
    $bits[] = $file[$i] & 1;
}

// Split LSB array into chunks of 8 bits.
$bytes = array_chunk($bits, 8);

// Implode byte arrays, convert to decimal, convert to ASCII.
foreach ($bytes as $byte)
{
echo chr(bindec(implode('', $byte)));
}
?>

我认为分裂和转换部分应该正常工作,但我认为在提取LSB时我犯了一个错误。有人能提供一个如何提取LSB的例子吗?

我稍微编辑了我的代码,以便我开始读取位置1的位。然后十进制表示在ASCII范围内,脚本输出一个实际的ASCII字符。

3 个答案:

答案 0 :(得分:1)

您可以简单地在for循环中构建位字符串,跳过整个数组过程:

$bits = '';
for ($i = 1; $i < strlen($file); $i++) {
    $bits .= (($file[$i] & 1) == 0) ? '0' : '1';
    if ($i % 8 == 0) {
       echo bindec($bits);
       $bits = '';
    }
}

当然,如果输入文件的大小不是8的倍数,你会有一些悬空位。

答案 1 :(得分:1)

如何将十六进制左移16次/ 2次?

$hex = 0x05;
$shiftVal = (0 + $hex)/2;
echo $hex>>$shiftVal;//should output 1

另一种方法是将十六进制转换为数字并查看它是奇数还是偶数:

$hex = 0xad;
echo $hex%2;

答案 2 :(得分:1)

许多程序员可能会对您的解决方案感到畏缩,但它与ASCIIEBCDIC的工作正常。我不知道任何其他可能与PHP一起使用的字符集。

字符数字的最低有效位与其表示的值相同。所以你的代码会起作用。但它确实应该有一个评论说明它依赖于ASCII / EBCDIC显示代码的最低位与数字相同。