計算字串的雜湊值

雖然在 awk 中實現標準雜湊演算法之一可能是一項繁瑣的工作,但定義一個可用作文字文件控制代碼的雜湊函式更容易處理。這種功能有用的實際情況是為給定描述的專案(例如測試用例)分配短 ID,以便短 ID 可以由使用者作為對專案的引用而不是提供其長描述。

雜湊函式需要字元轉換為數字程式碼,這是通過使用在指令碼的開始初始化查詢表來實現的。該雜湊然後函式使用模算術變換,非常經典的方法來雜湊計算來計算。

出於演示目的,我們新增了一個規則來使用它們的雜湊來裝飾輸入行,但是使用該函式不需要此規則:

BEGIN{
  for(n=0;n<256;n++) {
    ord[sprintf("%c",n)] = n
  }
}

function hash(text, _prime, _modulo, _ax, _chars, _i)
{
  _prime = 104729;
  _modulo = 1048576;
  _ax = 0;
  split(text, _chars, "");
  for (_i=1; _i <= length(text); _i++) {
    _ax = (_ax * _prime + ord[_chars[_i]]) % _modulo;
  };
  return sprintf("%05x", _ax)
}

# Rule to demonstrate the function
#  These comments and the following line are not relevant
#  to the definition of the hash function but illustrate
#  its use.

{ printf("%s|%s\n", hash($0), $0) }

我們將上面的程式儲存到 hash.awk 檔案中並在一個簡短的經典英文書名列表中進行演示:

awk -f hash.awk <<EOF
Wuthering Heights
Jane Eyre
Pride and Prejudice
The Mayor of Casterbridge
The Great Gatsby
David Copperfield
Great Expectations
The Return of the Soldier
Alice's Adventures in Wonderland
Animal Farm
EOF

輸出是

6d6b1|Wuthering Heights
7539b|Jane Eyre
d8fba|Pride and Prejudice
fae95|The Mayor of Casterbridge
17fae|The Great Gatsby
c0005|David Copperfield
7492a|Great Expectations
12871|The Return of the Soldier
c3ab6|Alice's Adventures in Wonderland
46dc0|Animal Farm

當應用於我最喜歡的小說的 6948 個非空行中的每一行時,這個雜湊函式不會產生任何碰撞。