JavaScript位运算哈希函数用异或、移位和加法快速打散字符串分布,适用于哈希表索引等轻量场景;推荐黄金比例乘法(0x9e3779b9)提升均匀性,并用hash & (table.length-1)映射桶索引(要求table.length为2的幂)。

用 JavaScript 位运算实现简单哈希函数,核心是利用 ^(异或)、>>>(无符号右移)、<<(左移)和 +(配合位截断)等操作,快速打散输入数据的分布,避免明显规律,同时保持计算高效。它不追求密码学安全,而是适用于哈希表索引、缓存键生成等轻量场景。
把字符串转成数字并持续异或
逐字符读取字符串,将每个字符的 ASCII 码与当前哈希值异或,并混入位移扰动:
function simpleHash(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
// 异或当前字符 + 左移 5 位 + 右移 2 位,增强雪崩效应
hash ^= str.charCodeAt(i) + (hash << 5) + (hash >>> 2);
}
return hash >>> 0; // 转为无符号 32 位整数,确保非负
}
说明:
- hash ^= ... 让每个字符影响整个状态,避免顺序无关性过强
- <<<> 相当于 ×32,<code>>> 2 相当于 ÷4,二者组合能快速扩散低位变化
- >> 0 是 JS 中最简捷的 32 位无符号整数转换方式,也隐式取模 2³²<<>
用黄金比例乘法进一步打散
在基础异或后,乘以一个“偏质数”(如 0x9e3779b9,即黄金分割比 φ 的近似整数)可显著提升分布均匀性:
用于端到端视频本地化流程的轻量编排器,路由至四个专注子技能——/wjs-transcribing-audio、/wjs-translating-subtitles...
function betterHash(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash ^= str.charCodeAt(i);
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return ((hash * 0x9e3779b9) >>> 0) & 0x7fffffff; // 保留 31 位正整数
}
说明:
- 多次移位+异或构成小型混淆轮(类似简化版哈希轮函数)
- 乘以 0x9e3779b9 是经典技巧,能将输入微小差异放大到高位
- 最后 & 0x7fffffff 确保结果为 31 位有符号正整数,适配多数数组索引场景
适配哈希表桶索引:取模或位与
得到哈希值后,需映射到固定大小的桶数组(如长度为 16 的哈希表)。推荐用位与代替取模,前提是桶数为 2 的幂:
- 若
table.length === 16(即 2⁴),可用hash & 15替代hash % 16,更快且无负数问题 - 通用写法:
hash & (table.length - 1),要求table.length必须是 2 的幂 - 若桶数非 2 的幂,仍可用
Math.abs(hash) % table.length,但注意Math.abs(-2147483648)会溢出,更稳写法是(hash >>> 0) % table.length
注意事项和局限性
这类位运算哈希适合内部工具、原型或性能敏感的非关键路径,但要注意:
- 对相似字符串(如
"abc"和"abd")可能产生相近哈希值,雪崩效应不如 MurmurHash 等专业算法 - 不抗碰撞,绝不用于签名、权限校验等安全场景
- 空字符串、单字符、重复字符等边界输入建议实测分布,必要时加入种子(如初始
hash = 0x1e3779b9)提升差异化 - ES6+ 中若需更高一致性,可结合
Array.from(str).reduce(...)写法,但性能略低

















