如何在不转换为字符串的情况下处理大的十六进制值?

How to work with large Hexadecimal values without converting to a string?

在 bash 我正在对我的打印机进行 SNMP 以获取一些信息,snmp 响应如下所示:

080118000001FFFB000000020000FFFFFFFD0007FFFEFFFAFFFE0011FFFEFFD507FB000FFF8E001C0006FFF9FFF2FFFE000100040005000600030002000100000007FFFDFFFEFFFE00020008FFFFFFFF0000000100000000FFFC0004FFFDFFFE00010002

根据开发文档,它指出 header 中的前四个 byte-long 元素是 第 6 个字节 18 可以用非常简单的 HEX 模式解释。例如,第 6 个字节为 18 HEX 的登录用户数,十进制为 24。其余数据以包含实部和虚部的两个字节增量定义 值,并且应该根据整个两个字节或 4 个半字节的 2 的补码来解释。

将这些转换为基于 10 的数字时,我是否必须将其转换为字符串并执行子字符串函数,或者 bash 中是否有一个函数允许我根据字节值进行转换.意思是我只想转换第 17 个字节?

使用bash

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

从字符串s到select子串18,我们使用bash的子串扩展:${s:4:2}。然后结合算术扩展,$((...)) 将十六进制数转换为十进制数。

使用 awk

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

工作原理

  • substr(,5,2)

    这是一个从第 5 个字符开始的 returns 2 个字符的子字符串。对于您的输入,此 returns 18

    因为 awk 使用索引原点 1 而不是 0,所以子字符串 18 在 awk 中从位置 1 开始。

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

    因为按照惯例,十六进制字符串以 0x 开头,这会将字符串 0x 添加到我们要求生成字符串 0x18

    [ 的子字符串中=52=]
  • strtonum("0x" substr(,5,2))

    这会将字符串 0x18 从十六进制转换为十进制。

bash中,您可以将值的任何子字符串视为十六进制数,并用

输出其十进制表示
$ value=080118000001FFFB000000020000FFFFFFFD0007FFFEFFFAFFFE0011FFFEFFD507FB000FFF8E001C0006FFF9FFF2FFFE000100040005000600030002000100000007FFFDFFFEFFFE00020008FFFFFFFF0000000100000000FFFC0004FFFDFFFE00010002

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

只需在所需的子字符串(这里是从字符串开头的偏移量 4 开始的两个字节)前加上 16# 并在算术表达式 ($(( ... ))).[=14 中对其进行计算=]