Что противоположно od (1)? - PullRequest
       18

Что противоположно od (1)?

6 голосов
/ 27 апреля 2009

Скажите, что у меня есть 8b1f 0008 0231 49f6 0300 f1f3 75f4 0c72 f775 0850 7676 720c 560d 75f0 02e5 ce00 0861 1302 0000 0000, как я могу легко получить двоичный файл из этого без копирования + вставки в шестнадцатеричный редактор?

Ответы [ 5 ]

14 голосов
/ 27 апреля 2009

Использование:

% xxd -r -p in.txt out.bin
4 голосов
/ 27 апреля 2009

См. xxd .

1 голос
/ 22 сентября 2016

Все представленные ответы относятся к удобному подходу xxd -r, но для ситуаций, когда xxd недоступен или удобен, здесь более переносимое (и более гибкое, но более подробное и менее эффективное) решение, использующее только POSIX. Синтаксис оболочки (он также компенсирует нечетное количество цифр на входе):

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

Между прочим: вы не указываете, является ли ваш ввод байтов с прямым порядком байтов или байтов с прямым порядком байтов, или хотите ли вы вывод с большим / младшим порядком байтов. Обычно входные данные, такие как в вашем вопросе, будут иметь порядок с прямым порядком байтов / сетью (например, созданный od -t x1 -An -v), и ожидается, что они преобразуются в выходные данные с прямым порядком байтов. Я предполагаю, что xxd просто предполагает, что по умолчанию, если не указано иное, и это решение делает то же самое. Если требуется замена байтов, то как вы делаете замену байтов, также зависит от размера слова в системе (например, 32-битная, 64-битная) и очень редко - байтовый размер (вы можете почти всегда предполагать 8-битную байты - октеты - хотя).

В приведенных ниже функциях используется более сложная версия трюка binary -> od -> binary для переноса байтных данных с байт-свопом, с учетом системного порядка байтов и учета системного размера слова. Алгоритм работает для всего до 72-битного слова (потому что seq -s '' 10 -> 12345678910 не работает):

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
}

Вы можете использовать вышеперечисленное для вывода содержимого файла в бигендовском формате независимо от системного порядка байтов:

if sys_bigendian; then
    cat /bin/sh
else
    cat /bin/sh | byte_swap $(sys_word_size)
fi
0 голосов
/ 16 марта 2016

Эта версия также будет работать с двоичным форматом:

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

Дополнительный символ '\ r' - это просто, если вы имеете дело с текстовыми файлами w / dos ... и обрабатывать побайтно для предотвращения разницы в порядках байтов, если в разных системах используются части трубы.

0 голосов
/ 03 августа 2014

Вот способ изменить вывод "od":

echo "test" | od -A x -t x1 | sed -e 's|^[0-f]* ?||g' | xxd -r
test
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...