Home > OS >  How to calculate Adler32 checksum for zip in Bash?
How to calculate Adler32 checksum for zip in Bash?

Time:03-25

I need get checksum Adler32 and store to variable in bash. It will be used in automatic script and it will be useful if no additional app/liberty will used which user need to install. Is it possible to use common / basic command Bash command to get this value?

CodePudding user response:

This is monumentally slow (about 60,000 times slower than C), but it shows that yes, it is possible.

#!/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

Hopefully someone who actually knows bash could vastly improve on this.

CodePudding user response:

Maybe this solution?:

python -c "import zlib; print(zlib.adler32(\"${file}\"))"

CodePudding user response:

Tried two adler bash functions one with an ordination dictionary and one with printf also tried some bit shifting like instead of sum1=(sum1 val)e521 -> temp= (sum1 val),sum1=temp >> 16 *15 (temp & 65355)e521 wasn't able to improve it a lot, perhaps somebody knows a faster one.

last function is a awk function, it is the fastest, works also on files.

#!/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 "x" $(( (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"
  • Related