Назад | Перейти на главную страницу

Запись шестнадцатеричных значений в файл (не в виде значений ascii) через командную строку

Мне было интересно, знает ли кто-нибудь об утилите командной строки, которая позволила бы мне напрямую записывать шестнадцатеричные значения в файл. таким образом, когда выполняется шестнадцатеричный дамп файла, значения, которые я ввожу, будут выплевываться. Жизненно важно, чтобы я записывал непосредственно в шестнадцатеричный формат, поскольку многие значения, которые мне нужно записать, не имеют связанных с ними символов, эквивалентных Unicode или ascii. Ищу что-то вроде:

writehex f6050000 ac7e0500 02000800 01000000 newfile
hexdump newfile 
hexdump 1.02
ts.event.1
00000000: f6050000 ac7e0500 02000800 01000000 .....~..........
16 bytes read

Эта функция Bash должна работать на вас:

writehex  ()
{
    local i
    while [ "$1" ]; do
        for ((i=0; i<${#1}; i+=2))
        do
            printf "\x${1:i:2}";
        done;
        shift;
    done
}

Альтернативная реализация:

writehex  ()
{
    local arg, i
    for arg; do
        for ((i=0; i<${#arg}; i+=2))
        do
            printf "\x${arg:i:2}"
        done
    done
}

Чтобы проверить это:

$ writehex abc00001ff | hexdump -C
00000000  ab c0 00 01 ff                                    |.....|
00000005

$ writehex f6050000 ac7e0500 02000800 01000000 | hexdump -C
00000000  f6 05 00 00 ac 7e 05 00  02 00 08 00 01 00 00 00  |.....~..........|
00000010

Другой вариант - использовать xxd.

$ echo hello | xxd
0000000: 6865 6c6c 6f0a
$ echo hello | xxd | xxd -r
hello

Редактировать:

Кроме того, вы можете использовать -p возможность принимать входные данные произвольной формы:

$ echo 'f6050000 ac7e0500 02000800 01000000' | xxd -r -p | hexdump -C
00000000  f6 05 00 00 ac 7e 05 00  02 00 08 00 01 00 00 00  |.....~..........|
00000010

Изменить 2:

Модифицированная функция выше для обработки нескольких входных аргументов (строки шестнадцатеричных цифр, разделенных пробелами).

С участием perl:

perl -ne '@a=split;for(@a){print chr(hex($_))}' inputfile > outputfile

Где содержание inputfile форматируется:

42 43 44

outputfile тогда будет содержать BCD. Вы можете подготовить входной файл в vi вот так:

:%s/ //g
:%s/\(.\{2\}\)/\1 /g

Это удалит все пробелы, а затем вставит пробел между каждым символом.

Пример, который вы привели, используя это perl линия:

$ cat inputfile
f6 05 00 00 ac 7e 05 00 02 00 08 00 01 00 00 00
$ hexdump outputfile
0000000 f6 05 00 00 ac 7e 05 00 02 00 08 00 01 00 00 00
0000010

А как насчет шестнадцатеричного редактора, такого как hexedit или hexer? Вы можете напрямую редактировать файл и вводить с ними значения в шестнадцатеричном формате.

Просто был такой же вызов и нашел это решение. Я попытался использовать решение от Денниса Уильямсона, но оно было очень медленным при реализации в массовом порядке (приходилось преобразовывать ~ 60 тыс. Sqlite blobs в файлы). Я придумал повторную реализацию writehex которым я хотел здесь поделиться:

writehex ()
{
  HEX=$(echo $1 | sed -re 's:([0-9A-F]{2}):\\x\1:g')
  echo -e $HEX
}

Когда дело доходит до производительности, преимуществом является то, что он просто использует один вызов sed и легкое регулярное выражение. Ваш пробег может отличаться, но я обнаружил, что это намного быстрее.