我试图按原样在bash中回显整数,而不将每个数字转换为ASCII并输出相应的序列。 e.g。
echo "123" | hd
00000000 31 32 33 0a |123.|
它输出每个字符的ASCII码。如何输出123本身,例如无符号整数?所以我得到像
这样的东西00000000 0x7B 00 00 00
答案 0 :(得分:2)
这是printf
$ printf "\x$(printf '%x' "123")" | hd
00000000 7b |{|
内部printf将十进制数123转换为十六进制,外部printf使用\x
创建一个具有该值的字节。
如果你想要几个字节,请使用:
$ printf '%b' "$(printf '\\x%x' "123" "96" "68")" | hd
00000000 7b 60 44 |{`D|
或者,如果你想使用十六进制:
$ printf '%b' "$(printf '\\x%x' "0x7f" "0xFF" "0xFF")" | hd
00000000 7f ff ff |...|
或者,在这种情况下,简单地说:
$ printf '\x7f\xFF\xFF' | hd
00000000 7f ff ff |...|
答案 1 :(得分:1)
你必须小心结束。 x86是little endian所以你必须先存储最低有效字节。
例如,如果要在磁盘上存储32位整数:2'937'252'660d = AF'12'EB'34h,则必须写入:0x34,然后是0xEB,然后是0x12,然后是0xAF,按此顺序。
使用此帮助程序的目的与您的目的相同:
printf "%.4x\n" 2937252660 | fold -b2 | tac | while read a; do echo -e -n "\\x${a}"; done
printf
从dec base更改为hex base
fold
按2个字符组分组,即1个字节
tac
反转行(这是应用little-endian的地方)
while
循环回显一个原始字节
答案 2 :(得分:0)
借用@Setop's answer的观察结果,示例暗示OP需要uint32s,但试图建立一个更有效的实现(不涉及子shell或外部命令):
print_byte() {
local val
printf -v val '%02x' "$1"
printf '%b' "\x${val}"
}
print_uint32() {
print_byte "$(( ( $1 / (( 256 ** 0 )) ) % 256 ))"
print_byte "$(( ( $1 / (( 256 ** 1 )) ) % 256 ))"
print_byte "$(( ( $1 / (( 256 ** 2 )) ) % 256 ))"
print_byte "$(( ( $1 / (( 256 ** 3 )) ) % 256 ))"
}
因此:
print_uint32 32 | xxd # this should be a single space, padded with nulls
...正确收益:
00000000: 2000 0000 ...
...正如Python struct.unpack()
模块反转回原始值所证明的那样:
$ print_uint32 32 |
> python -c 'import struct, sys; print struct.unpack("I", sys.stdin.read())'
32