问题描述
|
我有一个带有十六进制代码的文件,我需要从文件的每个字节中获取所有最低有效位,将它们连接起来,将它们分成8组,然后将字节转换为ASCII。我的问题是从每个字节中提取LSB。
十六进制文件如下所示(但更长):
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字符。
解决方法
您可以简单地在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的倍数,则可能会有一些悬挂。
, 许多程序员可能会对您的解决方案感到畏缩,但是它对于ASCII和EBCDIC都可以正常工作。我不知道PHP可能会使用其他任何字符集。
字符数字的最低有效位与其代表的值相同。这样您的代码就可以了。但是,确实值得发表评论,说明它依赖于ASCII / EBCDIC显示代码的最低有效位与数字相同。
, 将hexvalue左移/ 2次怎么办?
$hex = 0x05;
$shiftVal = (0 + $hex)/2;
echo $hex>>$shiftVal;//should output 1
另一种方法是将十六进制转换为数字,看看它是奇数还是偶数:
$hex = 0xad;
echo $hex%2;