【问题标题】:Breaking down a long string and then converting hex to decimal分解一个长字符串,然后将十六进制转换为十进制
【发布时间】:2021-04-08 16:14:58
【问题描述】:

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

00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033B2E3C9FD0803CE8000000000000000000000000000000000000000000000D610B7305BB52FC30A0000000000000000000000000000000AF298D050E4395D69670B12B7F410000000000000000000000000000000000000000000000000000000000000000000000000000

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

0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000033B2E3C9FD0803CE8000000
000000000000000000000000000000000000000D610B7305BB52FC30A0000000
000000000000000000000000AF298D050E4395D69670B12B7F41000000000000
0000000000000000000000000000000000000000000000000000000000000000

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

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

【问题讨论】:

  • 你可能需要split -b 64?

标签: bash awk hex


【解决方案1】:

另一种解决方案

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

0
1000000000000000013287555072
1060000000000000004189203726336
1000000000000000043845843045076197354634048000000
0

【讨论】:

    【解决方案2】:

    另一种方法是使用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'或其他无关字符终止时才需要)

    您可以将长字符串通过管道传输到上面的 sn-p,也可以将字符串重定向到循环。例如,在文件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: = " 前缀。您可以调整输出以满足您的需求。

    【讨论】:

    • 转换后的值似乎是四舍五入的。
    • 嗯...我没听懂。这似乎是obase/ibasebc 转换的结果,并且与@glennjackman 得到的结果相匹配。我得看看那里发生了什么。鉴于所涉及的值超过了 64 位的数量级,很明显已经完成了大数计算。
    • 也不确定我的版本是否正确,但数字不太可能是 10 的精确幂。
    • 我在:)上完全同意你的看法
    【解决方案3】:

    这是一种方法:

    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
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-31
        • 2012-02-03
        • 1970-01-01
        相关资源
        最近更新 更多