Как работать с большими шестнадцатеричными значениями без преобразования в строку?

В bash я запускаю свой принтер по SNMP, чтобы получить некоторую информацию, ответ snmp выглядит так:

080118000001FFFB000000020000FFFFFFFD0007FFFFEFFFFFE0011FFFFEFFD507FB000FFF8E001C0006FFF9FFF2FFFE00010004000500060003000200010000000720002000100000007FFFDFFFFEFFFEFE00020008FFFFFFF0000000100000000FFFC0004FFFDFFFE00010002.FFFDFFFE00010002.

На основе документации по разработке указано, что первые четыре байтовых элемента в заголовке должны быть 6-м байтом, то есть 18, можно интерпретировать в шестнадцатеричном режиме, что довольно прямолинейно. Например, количество зарегистрированных пользователей, которое в 6-м байте равно 18 HEX, в десятичном виде равно 24. Остальные данные определяются в двухбайтовых приращениях, содержащих действительные и мнимые значения, и должны интерпретироваться в соответствии с дополнением до 2 по всем двум байтам или 4 полубайтам.

При преобразовании этих чисел в 10 на основе мне нужно преобразовать их в строку и выполнить функции подстроки или есть функция в bash, которая позволит мне преобразовать ее на основе значения байта. То есть я просто хочу преобразовать 17-й байт?


person justZito    schedule 03.08.2015    source источник


Ответы (2)


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

$ s='0801180000...'
$ b=0x${s:4:2}
$ echo $((b))
24

Чтобы выбрать подстроку 18 из строки s, мы используем расширение подстроки bash: ${s:4:2}. Затем это объединяется с арифметическим расширением $((...)) для преобразования шестнадцатеричного числа в десятичное.

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

$ echo '0801180000...' | awk '{print strtonum("0x" substr($1,5,2));}'
24

Как это работает

  • substr($1,5,2)

    Это возвращает 2-символьную подстроку, начинающуюся с 5-го символа. Для вашего ввода это возвращает 18.

    Поскольку awk использует и индекс начала 1, а не 0, подстрока 18 начинается с позиции 1 в awk.

  • "0x" substr($1,5,2)

    Поскольку по соглашению шестнадцатеричные строки начинаются с 0x, это добавляет строку 0x к подстроке, которую мы запросили, чтобы создать строку 0x18.

  • strtonum("0x" substr($1,5,2))

    Это преобразует строку 0x18 из шестнадцатеричной в десятичную.

person John1024    schedule 03.08.2015

В bash вы можете рассматривать любую подстроку значения как шестнадцатеричное число и выводить его десятичное представление с помощью

$ value=080118000001FFFB000000020000FFFFFFFD0007FFFEFFFAFFFE0011FFFEFFD507FB000FFF8E001C0006FFF9FFF2FFFE000100040005000600030002000100000007FFFDFFFEFFFE00020008FFFFFFFF0000000100000000FFFC0004FFFDFFFE00010002

$ echo $(( 16#${value:4:2} ))
24

Просто добавьте к нужной подстроке (здесь два байта, начиная со смещения 4 от начала строки) префикс 16# и оцените ее внутри арифметического выражения ($(( ... ))).

person chepner    schedule 03.08.2015