Вывести 64-битное целое число с hexdump

В настоящее время я работаю над некоторыми двоичными данными.
Для проверки и отладки данных, ранее созданных моим приложением, я использую шестнадцатеричного, лицом к препятствию hexdump не представляется возможным извлечь 64-битное целочисленное поле.
Приведен следующий минимальный пример:

#include <iostream>
#include <fstream>
#include <cstdint>

int main(int argc, char** argv){
std::ofstream os("tmp.bin", std::ios::out | std::ios::binary);
uint64_t x = 7;
os.write((char*)&x,sizeof(uint64_t));
os.close();
return 0;
}

Я выполняю простой hexdump в моей системе:

hexdump tmp.bin

> 0000000: 0007 0000 0000 0000
> 0000008:

Теперь попробуем извлечь целое число без знака 64-битной ширины:

hexdump -e '/8 "%u"' tmp.bin

> hexdump: bad byte count for conversion character u

По хорошо написанному hexdump-руководство по Дэвид Мэйр это должно быть возможно, но у меня нет успеха.

Что мне не хватает?

3

Решение

Наш последний обходной путь выглядит следующим образом:

x=`hexdump -n 8 -e '2/4 "%08X " "\n"' {FILENAME} | awk 'BEGIN{printf "0x"}{print $2$1}'`
echo $(($x))

Пояснения к каждой части:

  • Извлечь восемь байтов 64-битного целочисленного значения из файла {FILENAME}
    в виде двух четырехбайтовых фрагментов, напечатанных в виде шестнадцатеричных кодированных значений.

    hexdump -n 8 -e '2/4 "%08X " "\n"' {FILENAME}
    
  • Инвертирует порядок байтов двух блоков и печатает их как один блок из восьми байтов, представляющий двоичное значение. Prepend 0x для последующей обработки.

    awk 'BEGIN{printf "0x"}{print $2$1}
    
  • Сохраните шестнадцатеричное представление в x для оценки bash.

    x=`....`
    
  • Пусть оболочка bourne интерпретирует и выводит шестнадцатеричное закодированное значение 64-битной целочисленной переменной (здесь предварительно добавленный 0x нужно).

    echo $(($x))
    
3

Другие решения

Можно также использовать sed. Следующее соответствует 8-байтовым шестнадцатеричным целым числам и заменяет их. Опять же, это работает только для целых чисел без знака.

hexdump ... | sed 's/0x\([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)/0x\2\1/'

AFAICT нужно уметь писать гораздо понятнее

hexdump ... | sed 's/0x\([0-9a-f]{8,8}\)\([0-9a-f]{8,8}\)/0x\2\1/'

обычно с некоторым параметром командной строки, таким как -E, чтобы включить расширенные регулярные выражения, но по крайней мере в Mac OS X 10.10 это не работает.

1

По вопросам рекламы [email protected]