используя bash: записать битовое представление целого числа в файл - PullRequest
14 голосов
/ 30 апреля 2010

У меня есть файл с двоичными данными, и мне нужно заменить несколько байтов в определенной позиции. Я придумал следующее, чтобы направить bash к смещению и показать, что он нашел нужное место:

dd bs=1 if=file iseek=24 conv=block cbs=2 | hexdump

Теперь, чтобы использовать «file» в качестве вывода:

echo anInteger | dd bs=1 of=hextest.txt oseek=24 conv=block cbs=2

Кажется, это работает просто отлично, я могу просмотреть изменения, внесенные в шестнадцатеричном редакторе. Проблема в том, что «anInteger» будет записан как ASCII-представление этого целого числа (что имеет смысл), но мне нужно написать двоичное представление.

Я хочу использовать bash для этого, и сценарий должен работать на максимально возможном количестве систем (я не знаю, будет ли на целевой системе установлен python или что-либо еще).

Как мне сказать команде преобразовать входные данные в двоичный (возможно, из шестнадцатеричного числа)?

Ответы [ 9 ]

14 голосов
/ 01 мая 2010

printf более портативен, чем echo. Эта функция принимает десятичное целое число и выводит байт с таким значением:

echobyte () {
    if (( $1 >= 0 && $1 <= 255 ))
    then
        printf "\\x$(printf "%x" $1)"
    else
        printf "Invalid value\n" >&2
        return 1
    fi
}

$ echobyte 97
a
$ for i in {0..15}; do echobyte $i; done | hd
00000000  00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
00000010
11 голосов
/ 30 апреля 2010

Вы можете использовать echo для вывода определенных байтов, используя шестнадцатеричные или восьмеричные. Например:

echo -n -e \\x30 

выведет ascii 0 (0x30)

(- n удалить завершающий перевод строки)

6 голосов
/ 20 ноября 2011

xxd - лучший способ. xxd -r infile outfile примет шестнадцатеричное значение ascii в infile для исправления outfile, и вы можете указать определенную позицию в infile следующим образом: 1FE:55AA

5 голосов
/ 01 мая 2010

работал как удовольствие. Я использовал следующий код для замены 4 байтов в байте 24 в младшем порядке с двумя целыми числами (1032 и 1920). Код не усекает файл.

echo -e \\x08\\x04\\x80\\x07 | dd of=<file> obs=1 oseek=24 conv=block,notrunc cbs=4

Еще раз спасибо.

0 голосов
/ 18 августа 2017

В моем случае мне нужно было перейти от десятичного числового аргумента к фактическому 16-разрядному значению без знака с прямым порядком байтов. Это, вероятно, не самый эффективный способ, но он работает:

# $1 is whatever number (0 to 65535) the caller specifies
DECVAL=$1
HEXSTR=`printf "%04x" "$DECVAL"`
BYTEONE=`echo -n "$HEXSTR" | cut -c 1-2`
BYTETWO=`echo -n "$HEXSTR" | cut -c 3-4`
echo -ne "\x$BYTEONE\x$BYTETWO" | dd of="$FILENAME" bs=1 seek=$((0xdeadbeef)) conv=notrunc
0 голосов
/ 13 февраля 2017

В bash у printf есть опция -v, а во всех оболочках есть логические операторы.

Итак, вот простая форма в bash:

int2bin() {
  local i=$1
  local f
  printf -v f '\\x%02x\\x%02x\\x%02x\\x%02x' $((i&255)) $((i >> 8 & 255)) $((i >> 16 & 255)) $((i >> 24 & 255))
  printf "$f"
}
0 голосов
/ 21 июля 2015

У меня есть функция для этого:

# number representation from 0 to 255 (one char long)
function chr() { printf "\\$(printf '%03o' "$1")" ; return 0 ; }
# from 0 to 65535 (two char long)
function word_litleendian() { chr $(($1 / 256)) ; chr $(($1 % 256)) ; return 0 ; }
function word_bigendian() { chr $(($1 % 256)) ; chr $(($1 / 256)) ; return 0 ; }
# from 0 to 4294967295 (four char long)
function dword_litleendian() { word_lilteendian $(($1 / 65536)) ; word_litleendian $(($1 % 65536)) ; return 0 ; }
function dword_bigendian() { word_bigendian $(($1 / 65536)) ; word_bigendian $(($1 % 65536)) ; return 0 ; }

Вы можете использовать трубопровод или перенаправление, чтобы поймать результат.

0 голосов
/ 30 апреля 2010

Вы можете поместить желаемый ввод в файл и использовать опцию «if =» для dd, чтобы вставить именно тот ввод, который вы хотите.

0 голосов
/ 30 апреля 2010

Если вы готовы положиться на bc (что довольно часто встречается)

echo -e "ibase=16\n obase=2 \n A1" | bc -q

может помочь.

...