我需要獲取校驗和 Adler32 并存盤到 bash 中的變數。它將在自動腳本中使用,如果沒有使用用戶需要安裝的其他應用程式/自由,它將很有用。是否可以使用通用/基本命令 Bash 命令來獲取此值?
uj5u.com熱心網友回復:
這是非常慢的(大約比 C 慢 60,000 倍),但它表明是的,這是可能的。
#!/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 的人可以大大改進這一點。
uj5u.com熱心網友回復:
也許這個解決方案?:
python -c "import zlib; print(zlib.adler32(\"${file}\"))"
uj5u.com熱心網友回復:
嘗試了兩個 adler bash 函式,一個帶有排序字典,一個帶有 printf 還嘗試了一些位移,例如代替 sum1=(sum1 val)e521 -> temp= (sum1 val),sum1=temp >> 16 *15 (temp & 65355)e521 無法對其進行很大改進,也許有人知道更快。
最后一個函式是一個 awk 函式,它是最快的,也適用于檔案。
#!/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"
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/449205.html
