Convertir byte a secuencia de bits (binario) en Perl

Me he estado dando vueltas en la cabeza con esta pregunta durante las últimas horas; hay muchas preguntas similares por aquí, pero nada igual, y ninguna de las técnicas que he visto parece estar funcionando.

Tengo una secuencia de bytes (enteros) que he generado a partir de la entrada en mi programa; cada uno representa un valor de color rojo, verde o azul de un píxel en una imagen BMP. Básicamente, necesito extraer la representación de flujo de bits de cada byte; es decir, la secuencia binaria de ese byte.

He estado usando muchas variaciones diferentes de pack() y unpack(), pero no estoy saliendo con los resultados adecuados.

Por ejemplo:

sub convertToBinary {
    my $str = unpack("B32", pack("N", shift));
    return $str;
}

También probé:

my $str = unpack("b8", shift);,

my $str = unpack("B8", shift);,

my $str = unpack("b*", shift);

Y numerosas otras variaciones; ninguno de ellos parece estar funcionando. Sin embargo, no creo que sea demasiado difícil extraer el patrón de bits de un byte... solo ocho '1' o '0', ¿verdad?

¿Que me estoy perdiendo aqui?

preguntado el 28 de julio de 12 a las 00:07

¿Puede dar ejemplos específicos de posibles entradas y la salida deseada? -

Claro, eso ayudaría. El objetivo es encontrar caracteres codificados en .BMP, un ejercicio de estenografía. Cada píxel en el .BMP tiene un valor rojo, verde y azul, cada uno de los cuales se representa en un byte de código. Dentro de cada byte, el bit menos significativo se establecerá en cero y luego se codificará con un nuevo valor como parte del mensaje. Principalmente tengo lo que necesito, pero me cuesta extraer el valor bit a bit de cada byte. -

No quieres la representación de bits. Puedes usar bit a bit & para comprobar si un bit está establecido. Dicho esto, todavía eres increíblemente vago acerca de tu entrada.

Bien, trataré de ser concreto entonces. Mi entrada es un archivo .BMP. Todo el archivo. Lo leo y uso $offset = unpack("L", substr($bmp, 10, 4)); para encontrar dónde comienzan los datos de píxeles reales. Así que es una cadena para empezar. Entonces, dentro de un for bucle, yo uso $byte = unpack("CCC",substr($bmp, $offset + $counter, 1)); para extraer cada byte, así que termino con un valor de tres caracteres (o 3 dígitos, no estoy seguro exactamente) que representa la cantidad de rojo, verde o azul de un determinado píxel. Estoy probando el byte que contiene ese valor en una secuencia de bits, para poder buscar los caracteres ocultos:

Aunque es muy posible que en algún lugar antes de ese paso hice algo que me hizo perder el bit de mensaje codificado en cada byte:

2 Respuestas

Creo que estas buscando correr

sub convertToBinary {
  return sprintf '%08b', shift;
}

Respondido 28 Jul 12, 00:07

Eso funcionó, ¡gracias! Al menos, me permitió obtener una representación binaria correcta. Sin embargo, todavía estoy un poco atascado: escribí sobre eso más específicamente arriba. Ahora tengo la representación binaria, pero no estoy seguro de si he perdido exponencialmente bits no utilizados (que habrían albergado el mensaje), o si todavía lo estoy extrayendo incorrectamente. - nik

Según un comentario, en realidad desea verificar si se establece el bit menos significativo de un byte.

La solución depende de lo que entiendas por byte.

Si tiene un carácter de 8 bits:

if (ord("\xAC") & 0x01)

Si tiene un número de 8 bits:

if (0xAC & 0x01)

Respuesta original:

Parece que quieres la representación binaria de un byte. La solución depende de lo que entiendas por byte.

Si tiene un carácter de 8 bits:

unpack('B8', "\xAC")

sprintf('%08b', ord("\xAC"))

sprintf('%08b', unpack('C', "\xAC"))

Si tiene un número de 8 bits:

sprintf('%08b', 0xAC)

unpack('B8', chr(0xAC))

unpack('B8', pack('C', 0xAC))

Todo lo anterior produce la cadena. 10101100.

Respondido el 30 de enero de 18 a las 19:01

Si me equivoco, ¿podría especificar las entradas y salidas con mayor precisión? - Ikegami

Los programas sprintf ¡El método funciona para devolver una representación binaria! Gracias. - nik

Sin embargo, todavía tengo algunas dificultades; Escribí más sobre esto en un comentario anterior. Un poco de confusión: cuando lo hago print unpack('B8', 10);, produce 00110001. Cuando conecto esto en un convertidor de vuelta a decimal, obtengo 49, no estoy seguro de qué está pasando allí. nik

@Nik, esa no es una de las tres soluciones que presenté para números de 8 bits. Está utilizando una de las soluciones que espera un carácter de 8 bits. - Ikegami

@Nik, lo que sucede es que estás pasando los dos bytes/caracteres "10" ("\x31\x30"). Perl procede a dar la representación de bits de los primeros 8 ("00110001") - Ikegami

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.