news 2026/6/8 20:56:21

为什么 “Aa“ 和 “BB“ 的哈希值一样?聊聊 Java 里的“算法炸弹”

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
为什么 “Aa“ 和 “BB“ 的哈希值一样?聊聊 Java 里的“算法炸弹”
关注我们,设为星标,每天7:30不见不散,每日java干货分享

🗝️ 哈希表 (Hash Map):理想中的“闪电查询”

在程序员眼里,HashMap(或 Python 的dict, PHP 的Array) 是世界上最伟大的数据结构。

动作

代码行数 (理想状态)

描述

存数据

1 行

map.put("key", "value");

取数据

1 行

map.get("key");

复杂度

无论存了多少数据,查找速度都是瞬间的。

现实是:哈希表的快,建立在**“数据均匀分布”的假设上。如果所有数据都挤到了同一个“坑”里,哈希表就会退化成链表**,速度从跑车变成蜗牛


🏨 第一关:酒店前台的噩梦

比喻:
想象哈希表是一个有 10000 个房间的酒店。

  • 正常情况:客人来了,报名字算出哈希值,前台直接给他钥匙:“去 302 房”。大家分散在不同的房间。

  • 哈希碰撞:来了 10000 个客人,他们的名字经过计算,哈希值竟然全是 101

恐怖故事:

  1. 1. 第一个客人住进 101。

  2. 2. 第二个客人也指向 101,因为有人了,他只能在 101 后面搭个帐篷(链表)。

  3. 3. 第 10000 个客人来了,他要住进 101。

  4. 4. 前台必须先遍历前 9999 个帐篷,确认没有重名,才能让他住在最后。

后果:
原本瞬间完成的入住(),变成了漫长的排队()。
存 1 万个数据的总耗时,从 1 万次操作变成了1亿次() 操作。


🏴‍☠️ 第二关:精心构造的“炸弹”

你可能会说:“哪有那么巧,1 万个人哈希值都一样?”
黑客说:“我算出来的。”

场景:
大多数编程语言(Java, Python 早期版本, PHP, NodeJS)使用的哈希算法(如 DJB2, MurmurHash)都是公开且固定的。
在 Java 中:

  • • 字符串"Aa"的 HashCode 是2112

  • • 字符串"BB"的 HashCode 也是2112

恐怖故事:
黑客在家里写了个脚本,生成了 10 万个 HashCode 相同的字符串:
"AaAa", "AaBB", "BBAa", "BBBB", ...

黑客把这 10 万个字符串,封装成一个 JSON 对象,发给你的服务器:

POST /api/login { "AaAa": 1, "AaBB": 2, "BBAa": 3, ... (10万个) }

数据包大小可能只有2MB


🔥 第三关:CPU 的燃烧

场景:
你的服务器收到这个请求,开始解析 JSON,把它存入HashMap

恐怖故事:

  1. 1.解析第 1 个 Key:很快。

  2. 2.解析第 1000 个 Key:CPU 开始发热,因为要遍历前 999 个。

  3. 3.解析第 10000 个 Key:CPU 飙升到 100%,因为每存一个都要遍历几千次。

  4. 4.解析第 100000 个 Key:服务器彻底卡死。

后果:

  • 极低成本:黑客不需要每秒发几百万次请求(DDoS),他只需要每秒发1 个这样的 2MB 请求。

  • 极高伤害:你的 Tomcat/NodeJS 线程被这个解析任务完全卡死,无法处理其他用户的请求。服务器看起来像死机了一样。

这叫Algorithmic Complexity Denial-of-Service (算法复杂度拒绝服务攻击)


🛡️ 拆弹专家:随机化与红黑树

既然哈希算法是公开的,那就别让黑客猜到。

1. 随机化种子 (Randomized Hashing)

这是 Python (3.3+), Ruby, Rust 等语言的解法。
每次服务器启动时,生成一个随机种子
Hash(key) = Algorithm(key, random_seed)
效果:
黑客在自己电脑上算出的碰撞 Key,发到你的服务器上,由于种子不同,哈希值完全不同。碰撞失效。

2. 从链表升级为红黑树 (Treeify)

这是Java 8的解法。
HashMap的某个桶里的碰撞数量超过 8 个时,Java 会自动把链表转换为红黑树

  • • 链表查询复杂度: (慢)

  • • 红黑树查询复杂度: (快)
    效果:
    就算黑客发来了 10 万个碰撞 Key,服务器的处理速度虽然变慢了,但不至于卡死(从几分钟缩短到几毫秒)。


💡 终章:算法的阴暗面

最坏情况 (Worst Case)不仅仅是教科书上的理论,它是黑客手中的武器。
程序员通常只关注“平均时间复杂度”,而黑客专门盯着“最坏时间复杂度”。

推荐阅读 点击标题可跳转

50个Java代码示例:全面掌握Lambda表达式与Stream API

16 个 Java 代码“痛点”大改造:“一般写法” VS “高级写法”终极对决,看完代码质量飙升!

为什么高级 Java 开发工程师喜爱用策略模式

精选Java代码片段:覆盖10个常见编程场景的更优写法

提升Java代码可靠性:5个异常处理最佳实践

为什么大佬的代码中几乎看不到 if-else,因为他们都用这个...

还在 Service 里疯狂注入其他 Service?你早就该用 Spring 的事件机制了

看完本文有收获?请转发分享给更多人

关注「java干货」加星标,提升java技能

❤️给个「推荐 」,是最大的支持❤️

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 4:51:07

基于物联网的自动灌溉系统的设计与实现(有完整资料)

资料查找方式: 特纳斯电子(电子校园网):搜索下面编号即可 编号: CJ-32-2022-013 设计简介: 本设计是基于物联网的自动灌溉系统,主要实现以下功能: 1,OLED显示温湿度和…

作者头像 李华
网站建设 2026/6/5 1:13:27

基于物联网的血压计设计(有完整资料)

资料查找方式:特纳斯电子(电子校园网):搜索下面编号即可编号:CJ-32-2022-017设计简介:本设计是基于物联网的血压计设计,主要实现以下功能:1,通过OLED显示温度、心率和血压…

作者头像 李华
网站建设 2026/5/30 15:17:53

springboot学习资源推荐系统_开题报告_晓庄

目录 springboot学习资源推荐系统开题报告(晓庄) 项目技术支持可定制开发之功能亮点源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作 springboot学习资源推荐系统开题报告(晓庄) 背景与意义 S…

作者头像 李华
网站建设 2026/5/31 1:22:54

Windows IP 配置工具 v1.3 丨绿色便携版

Windows 网络 IP 配置工具 v1.3 是专为 Windows 系统打造的绿色便携网络管理工具,无需安装可直接使用,适配网络管理员与普通用户的网络 IP 配置需求,支持图形界面与命令行双模式操作,在原有功能基础上新增多项实用功能&#xff0c…

作者头像 李华
网站建设 2026/6/3 22:10:26

去除前导 0 的经典代码

【算法分析】 ● 前导 0(Leading Zero)指的是出现在数字或字符串开头、且在第一个非 0 数字之前的所有 0。 例如,"00123" 的前导 0 是开头的两个 0,去除后应为 "123";"000" 没有非 0 数…

作者头像 李华
网站建设 2026/5/30 16:12:45

主流小程序商城软件功能架构与服务模式对比分析

因移动互联网不断深入发展,小程序商城已成为众多企业开展数字化经营、创建私域流量的核心工具之一,它具有不用下载安装、即用即走的特性,并且借助微信等超级应用的海量用户基础,在获客成本、用户体验以及运营灵活性方面呈现出明显…

作者头像 李华