分解一个长字符串,然后将十六进制转换为十进制

Breaking down a long string and then converting hex to decimal

从另一个输出,我有一个长字符串:

00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033B2E3C9FD0803CE8000000000000000000000000000000000000000000000D610B7305BB52FC30A0000000000000000000000000000000AF298D050E4395D69670B12B7F410000000000000000000000000000000000000000000000000000000000000000000000000000

需要分解成64个字符的部分:

0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000033B2E3C9FD0803CE8000000
000000000000000000000000000000000000000D610B7305BB52FC30A0000000
000000000000000000000000AF298D050E4395D69670B12B7F41000000000000
0000000000000000000000000000000000000000000000000000000000000000

然后每一行都需要从十六进制转换为十进制,类似于 echo "obase=10; ibase=16; $hexNum" |公元前

十六进制部分很容易解决。我怀疑对长字符串的“awk”操作可以将其分解为 5 个变量.. 上面的 bc 命令可以将其转换为十进制。

这是一种方法:

input='00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033B2E3C9FD0803CE8000000000000000000000000000000000000000000000D610B7305BB52FC30A0000000000000000000000000000000AF298D050E4395D69670B12B7F410000000000000000000000000000000000000000000000000000000000000000000000000000'
parts=() nums=()
while [[ -n $input ]]; do parts+=("${input:0:64}"); input=${input:64}; done
for h in "${parts[@]}"; do nums+=( $(echo "obase=10; ibase=16; $h" | bc) ); done

declare -p parts nums
declare -a parts=([0]="0000000000000000000000000000000000000000000000000000000000000000" [1]="0000000000000000000000000000000000000000033B2E3C9FD0803CE8000000" [2]="000000000000000000000000000000000000000D610B7305BB52FC30A0000000" [3]="000000000000000000000000AF298D050E4395D69670B12B7F41000000000000" [4]="0000000000000000000000000000000000000000000000000000000000000000")
declare -a nums=([0]="0" [1]="1000000000000000000000000000" [2]="1060000000000000000000000000000" [3]="1000000000000000000000000000000000000000000000000" [4]="0")

如果你不需要坚持64位十六进制数,一个循环就够了:

nums=()
for ((i=0; i<${#input}; i+=64)); do
    nums+=( $(bc <<< "obase=10; ibase=16; ${input:i:64}") )
done

另一个解决方案

$ fold -w64 file | awk '{print strtonum("0x")}'

0
1000000000000000013287555072
1060000000000000004189203726336
1000000000000000043845843045076197354634048000000
0

另一种方法是使用read -n 64 ...一次读取64个字符,例如

while read -n 64 line && [ "${#line}" -eq 64 ]; do
    echo $line
    echo "value $(bc <<< "obase=10; ibase=16; $line")"
done

(注意: 第二个测试 [ "${#line}" -eq 64 ] 只有在长串数字有可能被 '\n' 终止时才有必要其他无关字符)

您可以将长字符串通过管道传输到上面的代码段,也可以将字符串重定向到循环。例如,如果您在文件 string 中进行长输入,您可以执行以下操作:

$ while read -n 64 line && [ "${#line}" -eq 64 ]; do
    echo $line
    echo "value $(bc <<< "obase=10; ibase=16; $line")"
done < string
0000000000000000000000000000000000000000000000000000000000000000
value: 0
0000000000000000000000000000000000000000033B2E3C9FD0803CE8000000
value: 1000000000000000000000000000
000000000000000000000000000000000000000D610B7305BB52FC30A0000000
value: 1060000000000000000000000000000
000000000000000000000000AF298D050E4395D69670B12B7F41000000000000
value: 1000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
value: 0

请注意,每个 64 字符字符串的转换值都遵循每个 64 字符行下方提供的 "value: = " 前缀。您可以调整输出以满足您的需要。

最后,我将字符串设置为变量(dc) 然后

line1=${dc:1:64}
line2=${dc:65:64}
line3=${dc:129:64}
line4=${dc:193:64}
line5=${dc:257:64}