djb2哈希函数中魔数5381的位模式001/010/100/000/101有何含义与关联?
djb2哈希函数魔数5381的二进制串含义及关联
一、001/010/100/000/101 b到底是什么?
这串是数字5381的分组二进制表示,拆解一下:
- 先把5381转成八进制,结果是
12405 - 把八进制的每一位拆成3位二进制(高位补零凑够3位),就得到了那串分割的二进制:
- 八进制
1→ 二进制001 - 八进制
2→ 二进制010 - 八进制
4→ 二进制100 - 八进制
0→ 二进制000 - 八进制
5→ 二进制101
- 八进制
- 末尾的
b是二进制的标识,用来明确这是二进制数值串。
二、这和5381作为魔数有啥关系?
djb2的核心计算逻辑是hash = hash * 33 + c(c是当前字符的ASCII值),5381的这个二进制分布是它被选作初始值的重要原因:
- 5381的二进制位里,
1的位置分散开,没有连续扎堆的情况,这种稀疏且均匀的位分布,在后续和33(二进制100001)、字符值运算时,能让每一位的变化更均匀地扩散到整个哈希值里。 - 要是初始值的二进制位连续扎堆,运算后很容易出现部分位一直是0或1的情况,会增加哈希碰撞的概率,而5381的这种分布能有效避免这个问题,让哈希结果更均匀。
顺便补充下原回答里的其他特性,帮你理解为啥选5381:
- 奇数:要是初始值是偶数,乘以33后还是偶数,会快速丢失低位信息,奇数能避免这个问题
- 质数:质数的因数只有1和自身,能减少和字符ASCII值的公因数重叠,降低碰撞概率
- 亏数:指这个数的所有真因数加起来比它本身小,能减少运算中数值膨胀的幅度,避免过早溢出(C语言无符号整数溢出会自动取模,但均匀膨胀能让哈希分布更稳定)
内容的提问来源于stack exchange,提问作者lxs602
相关产品推荐
相关产品推荐

