GNU/Linux >> Tutoriales Linux >  >> Linux

convertir archivo de texto de bits a archivo binario

Agregando el -r opción (modo inverso) a xxd -b en realidad no funciona según lo previsto, porque xxd simplemente no admite la combinación de estas dos banderas (ignora -b si se dan ambos). En su lugar, primero debe convertir los bits en hexadecimales. Por ejemplo, así:

( echo 'obase=16;ibase=2'; sed -Ee 's/[01]{4}/;\0/g' instructions.txt ) | bc | xxd -r -p > instructions.bin

Explicación completa:

  • La parte dentro de los paréntesis crea un bc guion. Primero establece la base de entrada en binario (2) y la base de salida en hexadecimal (16). Después de eso, el sed el comando imprime el contenido de instructions.txt con un punto y coma entre cada grupo de 4 bits, lo que corresponde a 1 dígito hexadecimal. El resultado se canaliza a bc .
  • El punto y coma es un separador de comando en bc , por lo que todo lo que hace el script es imprimir cada entero de entrada (después de la conversión base).
  • La salida de bc es una secuencia de dígitos hexadecimales, que se puede convertir en un archivo con el habitual xxd -r -p .

Salida:

$ hexdump -Cv instructions.bin
00000000  00 00 00 13 02 d1 20 83  00 73 02 b3 00 73 04 33  |...... ..s...s.3|
00000010  00 73 64 b3 00 00 00 13                           |.sd.....|
00000018
$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011  ....
00000004: 00000010 11010001 00100000 10000011  .. .
00000008: 00000000 01110011 00000010 10110011  .s..
0000000c: 00000000 01110011 00000100 00110011  .s.3
00000010: 00000000 01110011 01100100 10110011  .sd.
00000014: 00000000 00000000 00000000 00010011  ....

oneliner para convertir cadenas de 32 bits de unos y ceros en el binario correspondiente:

$ perl -ne 'print pack("B32", $_)' < instructions.txt > instructions.bin

qué hace:

  • perl -ne iterará a través de cada línea del archivo de entrada proporcionado en STDIN (instructions.txt )
  • pack("B32", $_) tomará una lista de cadenas de 32 bits ($_ que acabamos de leer de STDIN), y convertirlo a valor binario (alternativamente, podría usar "b32" si desea un orden de bits ascendente dentro de cada byte en lugar de un orden de bits descendente; ver perldoc -f pack para más detalles)
  • print luego enviaría ese valor convertido a STDOUT, que luego redirigiríamos a nuestro archivo binario instructions.bin

verificar:

$ hexdump -Cv instructions.bin
00000000  00 00 00 13 02 d1 20 83  00 73 02 b3 00 73 04 33  |...... ..s...s.3|
00000010  00 73 64 b3 00 00 00 13                           |.sd.....|
00000018

$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011  ....
00000004: 00000010 11010001 00100000 10000011  .. .
00000008: 00000000 01110011 00000010 10110011  .s..
0000000c: 00000000 01110011 00000100 00110011  .s.3
00000010: 00000000 01110011 01100100 10110011  .sd.
00000014: 00000000 00000000 00000000 00010011  ....

Mi respuesta original era incorrecta:xxd no puede aceptar ninguno -p o -r con -b ...

Dado que las otras respuestas son viables y en aras de "otra manera ", ¿qué tal lo siguiente:

Entrada

$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011

Salida

$ hexdump -Cv < instructions.bin
00000000  00 00 00 13 02 d1 20 83  00 73 02 b3 00 73 04 33  |...... ..s...s.3|
00000010  00 73 64 b3 00 00 00 13                           |.sd.....|
00000018

Canalización de Bash:

cat instructions.txt \
    | tr -d $'\n' \
    | while read -N 4 nibble; do 
        printf '%x' "$((2#${nibble}))"; \
      done \
    | xxd -r -p \
    > instructions.bin
  • cat - innecesario, pero usado para mayor claridad
  • tr -d $'\n' - elimina todas las líneas nuevas de la entrada
  • read -N 4 nibble - leer exactamente 4× caracteres en el nibble variables
  • printf '%x' "$((2#${nibble}))" convierte el nibble de binario a 1× carácter hexadecimal
    • $((2#...)) - convertir el valor dado de base 2 (binario) a base 10 (decimal)
    • printf '%x' - formatee el valor dado de base 10 (decimal) a base 16 (hexadecimal)
  • xxd -r -p - inversa (-r ) un volcado simple (-p ) - de hexadecimal a binario sin formato

Pitón:

python << EOF > instructions.bin
d = '$(cat instructions.txt | tr -d $'\n')'
print(''.join([chr(int(d[i:i+8],2)) for i in range(0, len(d), 8)]))
EOF
  • Un heredoc sin comillas (<< EOF ) se usa para obtener contenido en el código de Python
    • Esto no es eficiente si la entrada se vuelve grande
  • cat y tr - utilizado para obtener una entrada limpia (una línea)
  • range(0, len(d), 8) - obtener una lista de números desde 0 hasta el final de la cadena d , avanzando 8× caracteres a la vez.
  • chr(int(d[i:i+8],2)) - convertir el segmento actual (d[i:i+8] ) de binario a decimal (int(..., 2) ), y luego a un carácter sin formato (chr(...) )
  • [ x for y in z] - comprensión de listas
  • ''.join(...) - convertir la lista de caracteres en una sola cadena
  • print(...) - imprimirlo

Linux
  1. Bash Script:¿Comprobar si un archivo es un archivo de texto?

  2. ¿Cómo eliminar "datos binarios" de un archivo de texto (por ejemplo, Bash_history)?

  3. ¿Descomprimir un archivo .gz para obtener un archivo de texto pero obtener un archivo binario?

  4. ¿Cómo agrego texto a un archivo?

  5. Convierta una cadena de texto en bash en una matriz

Cómo convertir un archivo de Windows a un archivo UNIX

¿Cómo convertir un archivo ejecutable de Linux (binario) a un archivo exe de Windows?

¿Cómo extraer una porción de texto de un archivo binario en linux/bash?

¿Cómo convierto tar.bz2 a tar.gz?

¿Qué podría causar que el comando de archivo en Linux informe un archivo de texto como datos binarios?

¿Cómo convertir texto específico de una lista en mayúsculas?