常用校驗和(Hash)算法-Adler-32/CRC/Fnv-1/Fnv-1a


常用校驗和算法


Adler-32校驗和

記校驗和為\(C\)(32位), 其高16位記為\(s_2\), 低16位記為\(s_1\), 那么有\(C=s_2 * 2^{16} + s_1\). 記有數據字節流\(D[0..len]\) 算法過程如下:

\[\begin{aligned} & s_1 = 1u32 \\ & s_2 = 0u32 \\ & M = 65521(小於65536的最大質數) \\ & \quad \\ & for \quad d \quad in \quad D \\ & \qquad s_1 = (s_1 + d) \mod M \\ & \qquad s_2 = (s_1 + s_2) \mod M \\ & end \\ & \quad \\ & C = s_2 \ll 16 + s_1 \end{aligned} \]

CRC校驗

記有生成多項式\(G(x)\)的二進制表示\(g[0..m]\), 有字節流數據\(F(x)\)其二進制位表示為\(f[0..n]\), 記校驗和為\(C\)(m-1位), 算法流程如下:

\[\begin{aligned} & C = 0; g=g[0]*2^{0}+g[1]*2^{1}+\cdots+g[m-1]*2^{m-1} \\ & src = 0 \\ & \quad \\ & for \quad bit \quad in \quad f \\ & \qquad src = (src \ll 1) + bit\\ & \qquad if \quad src \ge g \\ & \qquad \qquad src = src \mod g\\ & \qquad end \\ & end \\ & C = src \end{aligned} \]

Fnv算法

Fnv算法目前在用的有兩個版本Fnv-1Fnv-1a. 記有校驗和\(C\)(共有\(2^{n}\)位), 有字節流數據\(D[0..len]\), 算法流程如下:

  • Fnv-1:

\[\begin{aligned} & C = INV \\ & for \quad d \quad in \quad D \\ & \qquad C = C * P \\ & \qquad C = C \oplus d \\ & end \end{aligned} \]

  • Fnv-1a:

\[\begin{aligned} & C = INV \\ & for \quad d \quad in \quad D \\ & \qquad C = C \oplus d \\ & \qquad C = C * P \\ & end \end{aligned} \]

  • \(x\oplus y\): x異或y;
  • INV: 初始Hash值;
  • P: 質數;

對於\(C\)不同的位長度, INV和P的值如下:

// 32位
INV = 2166136261;
P = 16777619;   // 2^24+2^8+0x93

// 64位
INV = 14695981039346656037;
P = 1099511628211;  // 2^40+2^8+0xb3

// 128位
INV = 0x6c62272e07bb014262b821756295c58d;
P = 0x13b+2^88;     // 2^88+2^8+0x3b


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM