首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何计算拉链的Adler32校验和?

如何计算拉链的Adler32校验和?
EN

Stack Overflow用户
提问于 2022-03-23 12:34:50
回答 3查看 303关注 0票数 0

我需要获得校验和Adler32并存储到bash中的变量。它将用于自动脚本,如果没有额外的应用程序/自由将使用的用户需要安装的话,它将是有用的。是否可以使用公共/基本命令Bash命令来获得这个值?

EN

回答 3

Stack Overflow用户

发布于 2022-03-24 05:11:55

这是非常慢(大约比C慢60,000倍),但它表明,是的,这是可能的。

代码语言:javascript
复制
#!/bin/bash
sum1=1
sum2=0
while LANG=C IFS= read -r -d '' -n 1 ch; do
  printf -v val '%d\n' "'$ch"
  (( val = val < 0 ? val + 256 : val, sum1 = (sum1 + val) % 65521, sum2 = (sum2 + sum1) % 65521 ))
done
(( adler = sum1 + 65536 * sum2 ))
echo $adler

希望真正了解bash的人能在这方面有很大的改进。

票数 1
EN

Stack Overflow用户

发布于 2022-03-24 13:03:52

也许这个解决方案?:

代码语言:javascript
复制
python -c "import zlib; print(zlib.adler32(\"${file}\"))"
票数 1
EN

Stack Overflow用户

发布于 2022-03-24 13:04:35

尝试了两个adler bash函数--一个带有排序字典,另一个带有printf --还尝试了一些类似于sum1= (sum1+val) %65521 -> temp= (sum1+val)的位移位函数,sum1=temp >> 16 *15 + (temp & 65355)%65521不能很好地改进它,也许有人知道更快的。

最后一个函数是awk函数,它是最快的,也工作在文件上。

代码语言:javascript
复制
#!/bin/bash

            a=$'Hello World'; b=""
            for ((i=0;i<1000;i++)); do b+=$a; done

            #-- building associative array ord byte character array
            declare -Ai ordCHAR=()
            for ((i=1;i<256;i++)); do printf -v hex "%x" $i; printf -v char "\x"$hex; ordCHAR[$char]=$i; done
            unset hex char i
            #-- building associative array ord byte character array -- END

            #-- with dictionary
            function adler32_A ()
                {
                local char; local -i sum1=1 sum2=0 val
                LC_ALL=C; while read -rN 1 char; do
                val=${ordCHAR[$char]};
                ((sum1=(sum1+val) % 65521, sum2 = (sum2 + sum1) % 65521 ))
                done <<< $1

                #-- removing 0A=\n addition, because of here string
                (( sum2-=sum1, sum2<0 ? sum2+=65521 :0, sum1-=val, sum1<0 ? sum1+=65521 :0 ));
                printf "%08x" $(( (sum2 << 16) + sum1 )) 
                LC_ALL=""
                }

            #-- with printf
            function adler32_B ()
                {
                local char; local -i sum1=1 sum2=0 val
                LC_ALL=C; while read -rN 1 char; 
                    do
                    printf -v val '%d' "'$char"
                    (( sum1 = (sum1 + val) % 65521, sum2 = (sum2 + sum1) % 65521 ))
                    done <<< $1
                #-- removing 0A=\n addition, because of here string
                (( sum2-=sum1, sum2<0 ? sum2+=65521 :0, sum1-=val, sum1<0 ? sum1+=65521 :0 ));
                printf "%x" $((sum1 + 65536 * sum2 ))
                LC_ALL=""
                }

            #-- call adler32_awk [text STR] [evaluate text as path bINT]
            function adler32_awk ()
                {
                local -i bPath=$2;
                awk -b \
            '   BEGIN {RS="^$"; bPath='"$bPath"'; for (i=0;i<256;i++) charOrdARR[sprintf("%c",i)]=i; A=1; B=0;}
                {
                recordSTR=substr($0,1,length($0)-1); if (bPath) {getline byte_data < recordSTR; close(recordSTR);} else byte_data=recordSTR;
                l=length(byte_data); for (i=1;i<=l;i++) {
                    A+=charOrdARR[substr(byte_data,i,1)]; if (A>65520) A-=65521;
                    B+=A; if (B>65520) B-=65521;}
                printf "%x", lshift(B,16)+A; }
            ' <<<$1
                }
            time adler32_A "$b"
            time adler32_B "$b"
            #-- adler 32 of file -> adler32_awk "/home/.../your file" 1
            time adler32_awk "$b"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71587325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档