2011-05-30 90 views
5

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

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字符。

回答

1

你可以简单地内建立的比特串循环,跳过整个阵列的过程:

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

当然,你有一些悬空位,如果输入文件的大小不是多的8.

+0

该代码仅用于一次性目的,因此我不关心速度或优点。但我有一个问题。为什么你用索引1开始循环,如果空格仍然在$ file字符串中,它会影响吗? – 2011-05-30 20:24:47

+0

当我写我的答案时,你的循环从0开始,并猜测我被循环定义中的预增值('++ $ i')抛出。 – 2011-05-30 20:55:06

1

如何将六角形左移六进制/ 2次?

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

另一种方法是十六进制转换为数字,看看它是否是奇数或偶数:

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

我是否需要将此应用于每个角色?因此,如果输入是“42 4D”,我是否适用于'42'和'4D',或者是否适用于'4','2','4'和'D'? – 2011-05-30 20:45:28

+0

一个十六进制数字由一组2个字符表示。因此,您应该将它应用于'42'和'4d'而不是每个字符分开 – 2011-05-30 21:16:06

+0

@Florian Eckerstorfer:增加了另一种方法。看编辑 – 2011-05-30 21:20:35

1

很多程序员可能会畏缩在您的解决方案,但它工作得既ASCII罚款和EBCDIC。我不知道任何其他可能使用PHP的字符集。

字符数字的最低有效位与它所表示的值相同。所以你的代码将起作用。但它真的值得有一个评论解释它依赖于ASCII/EBCDIC显示代码的最低有效位与数字相同。