2009-04-27 16 views
6

Digamos que tengo 8b1f 0008 0231 49f6 0300 f1f3 75f4 0c72 f775 0850 7676 720c 560d 75f0 02e5 ce00 0861 1302 0000 0000, ¿cómo puedo obtener fácilmente un archivo binario sin copiar y pegar en un editor hexadecimal?¿Qué es lo opuesto a od (1)?

+0

Escriba un script o programa simple y ejecútelo. 5-10 líneas de C, o cualquier otro idioma. Trato hecho. –

+0

Aquí está la cuestión del código de golf para este problema con una gran cantidad de soluciones: http://stackoverflow.com/questions/795027/code-golf-hex-to-raw-binary-conversion – dertoni

Respuesta

12

Uso:

% xxd -r -p in.txt out.bin 
0

Aquí está la forma de revertir "od" de salida:

echo "test" | od -A x -t x1 | sed -e 's|^[0-f]* ?||g' | xxd -r 
test 
0

Esta versión funciona con formato binario demasiado:

cat /bin/sh \ 
| od -A n -v -t x1 \ 
| tr -d '\r' \ 
| xxd -r -g 1 -p1 \ 
| md5sum && md5sum /bin/sh 

El extra " \ r 'es solo si está tratando con dos archivos de texto ... y procesa byte por byte para evitar la diferencia entre endians si ejecuta partes de tubería en diferentes sistemas.

1

Todas las respuestas presentes hacen referencia al práctico enfoque , pero para situaciones donde xxd no está disponible o es conveniente aquí hay una solución más portable (y más flexible, pero más detallada y menos eficiente), usando solo la sintaxis del shell POSIX (también compensa-número impar de dígitos de entrada):

un_od() { 
    printf -- "$(
     tr -d '\t\r\n ' | sed -e 's/^(.(.{2})*)$/0\1/' -e 's/\(.\{2\}\)/\\x\1/g' 
    )" 
} 

por cierto: no se especifica si su entrada es grande-endian o little-endian, o si desea grande/pequeño-endian salida. Por lo general, la entrada como en su pregunta sería big-endian/network-order (por ejemplo, creada por od -t x1 -An -v), y se esperaría que se transformara en salida big-endian. Supongo que xxd simplemente asume que el valor predeterminado si no se indica lo contrario, y esta solución también lo hace. Si se necesita el intercambio de bytes, la forma en que realiza el intercambio de bytes también depende del tamaño de palabra del sistema (por ejemplo, 32 bits, 64 bits) y muy raramente el tamaño de bytes (casi siempre puede suponer bytes de 8 bits - octetos - aunque).

Las siguientes funciones utilizan una versión más compleja del truco binary -> od -> binary para datos binarios de byteswinks portables, condicional a la permanencia del sistema y la contabilidad del tamaño de palabra del sistema. El algoritmo funciona para nada hasta 72bit palabra de tamaño (porque seq -s '' 10 ->12345678910 no funciona):

if { sed --version 2>/dev/null || :; } | head -n 1 | grep -q 'GNU sed'; then 
    _sed() { sed -r "${@}"; } 
else 
    _sed() { sed -E "${@}"; } 
fi 

sys_bigendian() { 
    return $(
     printf 'I' | od -t o2 | head -n 1 | \ 
      _sed -e 's/^[^ \t]+[ \t]+([^ \t]+)[ \t]*$/\1/' | cut -c 6 
    ) 
} 

sys_word_size() { expr $(getconf LONG_BIT)/8; } 

byte_swap() { 
    _wordsize=$1 
    od -An -v -t o1 | _sed -e 's/^[ \t]+//' | tr -s ' ' '\n' | \ 
     paste -d '\\' $(for _cnt in $(seq $_wordsize); do printf -- '- '; done) | \ 
     _sed -e 's/^/\\/' -e '$ s/\\+$//' | \ 
     while read -r _word; do    
      _thissize=$(expr $(printf '%s' "$_word" | wc -c)/4) 
      printf '%s' "$(seq -s '' $_thissize)" | tr -d '\n' | \ 
       tr "$(seq -s '' $_thissize -1 1)" "$_word" 
     done 
    unset _wordsize _prefix _word _thissize 
} 

Puede utilizar el contenido del archivo anterior a la salida en formato bigEndian independientemente del orden de bits del sistema:

if sys_bigendian; then 
    cat /bin/sh 
else 
    cat /bin/sh | byte_swap $(sys_word_size) 
fi 
Cuestiones relacionadas