常用校驗和算法
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-1
和Fnv-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