¿Cómo puedo crear un archivo binario con instructions.binlos mismos datos que instructions.txt? En otras palabras, el .binarchivo debe tener los mismos 192 bits que hay en el .txtarchivo, con 32 bits por línea. Estoy usando bash en Ubuntu Linux. Estaba tratando de usar, xxd -b instructions.txtpero la salida es mucho más larga que 192 bits.
perl -neiterará a través de cada línea de archivo de entrada proporcionada en STDIN ( instructions.txt)
pack("B32", $_)tomará una lista de cadenas de 32 bits ( $_que acabamos de leer de STDIN) y la convertirá en valor binario (alternativamente, podría usarla "b32"si quisiera un orden de bits ascendente dentro de cada byte en lugar de un orden de bits descendente; consulte perldoc -f packpara obtener más detalles)
print luego generaría ese valor convertido a STDOUT, que luego redirigimos a nuestro archivo binario instructions.bin
Agregar la -ropción (modo inverso) en xxd -brealidad no funciona según lo previsto, porque xxd simplemente no admite la combinación de estos dos indicadores (ignora -bsi se dan ambos). En su lugar, primero debes convertir los bits en hexadecimal. 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 bcscript. Primero establece la base de entrada en binario (2) y la base de salida en hexadecimal (16). Después de eso, el sedcomando imprime el contenido de instructions.txtcon un punto y coma entre cada grupo de 4 bits, que corresponde a 1 dígito hexadecimal. El resultado se canaliza a bc.
El punto y coma es un separador de comando bc, por lo que todo lo que hace el script es volver a imprimir cada entero de entrada (después de la conversión base).
La salida de bces una secuencia de dígitos hexadecimales, que se pueden convertir a un archivo con el habitual xxd -r -p.
Lo sentimos, todavía hay un error de endianness en esto. Trabajando en arreglarlo!
nomadictype
1
En realidad está bien. Estaba confundido anteriormente al usar el ancho de salida incorrecto en el último comando xxd.
nomadictype
1
He probado el guión y que funciona, pero salidas: (standard_in) 1: syntax error. ¿Puede explicar a qué syntax errorse refiere o por qué ocurre esto? ¿Esto también sucede en tu máquina?
dopamane
2
Mi respuesta original era incorrecto - xxdno puede aceptar cualquiera -po -rcon -b...
Dado que las otras respuestas son viables, y en interés de " otra forma ", ¿qué tal lo siguiente:
Nota: en muchos shells |al final de una línea funciona como una barra invertida: el comando continúa a la siguiente línea. De esta manera, puede deshacerse de algunas barras invertidas. No estoy seguro si el uso de símbolos de tubería después de LF fue su decisión informada. Menciono lo contrario en caso de que no lo supieras.
Kamil Maciorowski
1
No lo sabia, gracias! Me gusta dividir la tubería en líneas lógicas, y tener las tuberías |(o redirecciones >, operadores booleanos &&, etc.) explícitamente en el frente para visibilidad / claridad ... tal vez una cuestión de estilo / preferencia.
Attie
1
Después de algunas reflexiones, puedo comenzar a usar este estilo porque uno puede decir que las dos líneas están conectadas, examinando cualquiera de ellas. Si |está al final, la siguiente línea puede parecer un comando independiente, puede ser confuso. Es por eso que pensé que el estilo podría ser tu decisión informada.
(standard_in) 1: syntax error
. ¿Puede explicar a quésyntax error
se refiere o por qué ocurre esto? ¿Esto también sucede en tu máquina?Mi respuesta original era incorrecto -
xxd
no puede aceptar cualquiera-p
o-r
con-b
...Dado que las otras respuestas son viables, y en interés de " otra forma ", ¿qué tal lo siguiente:
Entrada
Salida
Tubería Bash:
cat
- innecesario, pero usado para mayor claridadtr -d $'\n'
- eliminar todas las nuevas líneas de la entradaread -N 4 nibble
- lee exactamente 4 × caracteres en lanibble
variableprintf '%x' "$((2#${nibble}))"
convierte el mordisco de binario a 1 × carácter hexadecimal$((2#...))
- convierte 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
- reverse (-r
) un volcado simple (-p
) - de hexadecimal a binario sin formatoPitón:
<< EOF
) sin comillas para obtener contenido en el código de Pythoncat
ytr
- se utiliza para obtener una entrada limpia (una línea)range(0, len(d), 8)
- Obtenga una lista de números desde 0 hasta el final de la cadenad
, paso a paso 8 × caracteres a la vez.chr(int(d[i:i+8],2))
- convierte 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]
- lista de comprensión''.join(...)
- convierte la lista de caracteres en una sola cadenaprint(...)
- Imprímelofuente
|
al final de una línea funciona como una barra invertida: el comando continúa a la siguiente línea. De esta manera, puede deshacerse de algunas barras invertidas. No estoy seguro si el uso de símbolos de tubería después de LF fue su decisión informada. Menciono lo contrario en caso de que no lo supieras.|
(o redirecciones>
, operadores booleanos&&
, etc.) explícitamente en el frente para visibilidad / claridad ... tal vez una cuestión de estilo / preferencia.|
está al final, la siguiente línea puede parecer un comando independiente, puede ser confuso. Es por eso que pensé que el estilo podría ser tu decisión informada.También puede intentar publicar esto en el sitio de CodeGolf SE, pero aquí está mi versión alternativa de Python (solo para desafío de patada):
Suponiendo que
input.txt
contiene sus datos, y está formateado a 32 caracteres por línea.Esto usa el
struct
paquete Python 3 y la escritura / lectura para stdin / out. (En Python 2 hubiera sido más corto).fuente