2011-05-30 15 views
5

Tengo un archivo con código hexadecimal y necesito obtener todos los bits menos significativos de cada byte en el archivo, concatenarlos, dividirlos en grupos de 8 y luego convertir los bytes en ASCII. Mi problema es extraer el LSB de cada byte.Obtiene Bit menos significativo en PHP desde Hex

El archivo hexadecimal se parece a esto (pero es mucho más larga):

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 

Mi código es el siguiente:

<?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))); 
} 
?> 

Creo que la división y la parte de conversión deberían funcionar correctamente, pero Creo que cometí un error al extraer el LSB. ¿Alguien puede dar un ejemplo de cómo puedo extraer el LSB?

He editado ligeramente mi código, de modo que empiezo a leer los bits en la posición 1. Entonces la representación decimal está dentro del rango ASCII y el script genera un carácter ASCII real.

Respuesta

1

Simplemente podría construir la cadena de bits dentro del bucle, saltándose todo el procedimiento matriz:

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

Por supuesto, tendría que algunos bits colgantes si el tamaño del archivo de entrada no es un múltiplo de 8.

+0

El código es solo para un propósito de tiempo, por lo tanto, no me importó la velocidad o el bien. Pero tengo una pregunta. ¿Por qué inicias el ciclo con el índice 1 y importa si los espacios aún están dentro de la cadena $ file? –

+0

En el momento en que escribí mi respuesta, tu loop comenzaba en 0, y supongo que fui descartado por el preincremento ('++ $ i') en la definición del ciclo. –

1

¿Qué hay de cambiar el hexágono izquierdo para hexvalue/2 veces?

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

Otro enfoque consiste en convertir el hexadecimal a un número y ver si es par o impar:

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

¿Debo aplicar esto a cada personaje? Por lo tanto, si la entrada es '42 4D', ¿aplico a' 42' y '4D' o aplico a' 4', '2',' 4' y 'D'? –

+0

un número hexadecimal está representado por un grupo de 2 caracteres ... por lo que debe aplicarlo a '42' y' 4d' no a cada carácter por separado –

+0

@Florian Eckerstorfer: agregó otro método. ver edición –

1

Una gran cantidad de programadores puede encogerse en su solución, pero funciona muy bien tanto con ASCII y EBCDIC. No sé de ningún otro juego de caracteres que uno posiblemente pueda estar usando con PHP.

El bit menos significativo del dígito del carácter es el mismo que el valor que representa. Entonces tu código funcionará. Pero realmente merece un comentario explicando que se basa en que el bit menos significativo de los códigos de visualización ASCII/EBCDIC es el mismo dígito.

Cuestiones relacionadas