JavaScript字符串哈希可用算术运算符实现:遍历字符,用charCodeAt()获取Unicode码点,通过乘加取模组合(如累加后对质数取模),控制结果在指定范围内,适用于哈希表、缓存或简易去重。

JavaScript 中可以用算术运算符对字符串做简单哈希,核心思路是:遍历字符,把每个字符的 Unicode 码点(charCodeAt())通过乘法、加法和取模组合起来,控制结果在合理范围内(比如数组索引范围)。这不是密码学安全哈希,但适合实现哈希表、缓存键映射或简易去重。
基础线性累加 + 取模
最简方式:把每个字符的码点相加,再对一个质数取模(减少冲突):
function simpleHash(str, size = 100) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash += str.charCodeAt(i);
}
return hash % size;
}缺点是顺序无关("ab" 和 "ba" 结果相同),且易冲突。适合教学或极轻量场景。
带权重的多项式滚动(DJB2 风格)
更实用的做法:用乘法引入位置权重,类似经典 DJB2 算法(使用位运算或乘法模拟):
立即学习“Java免费学习笔记(深入)”;
function djb2Hash(str, size = 100) {
let hash = 5381; // 初始值,选质数有助于分散
for (let i = 0; i < str.length; i++) {
hash = ((hash << 5) + hash) + str.charCodeAt(i); // hash * 33 + char
}
return Math.abs(hash) % size;
}说明:
hash 是 <code>hash * 32的快速写法,加上原hash就是hash * 33- 初始值 5381 是经验值,能提升低位变化敏感度
-
Math.abs()防止大数导致负余数(JavaScript 取模可为负)
支持数字/布尔等基本类型的通用哈希函数
可扩展为处理多种类型,统一转为字符串再哈希:
function universalHash(value, size = 100) {
const str = String(value); // null → "null", true → "true", 42 → "42"
let hash = 5381;
for (let i = 0; i < str.length; i++) {
hash = (hash * 31 + str.charCodeAt(i)) & 0x7fffffff; // 用 31(常用质数),并强制非负
}
return hash % size;
}注意:& 0x7fffffff 是按位与,清掉符号位,比 Math.abs 更快;乘数 31 在 Java 中广泛使用,效果稳定。
实际使用建议
这类算术哈希适用于:
- 手写简易哈希表(如用数组模拟 bucket)
- 前端缓存 key 归一化(例如
cache[universalHash(url)]) - 避免重复渲染时生成稳定短标识(非唯一,需配合内容比对)
不适用于:
- 需要加密安全性的场景(如签名、密码存储)——请用
SubtleCrypto - 要求强唯一性或抗碰撞的业务逻辑——应改用
crc32或murmurhash等成熟算法
不复杂但容易忽略细节:始终控制输出范围、处理负数、选择合适质数作模数或乘子,就能让算术哈希既快又够用。


















