md5() 不该用于密码存储,因其是无盐的确定性哈希,易受彩虹表和碰撞攻击;应使用 password_hash()。它适用于文件校验、缓存键等非安全场景,注意编码、大小写和换行符一致性。

PHP 的 md5() 函数不是加密,它只是计算哈希值;如果你需要不可逆的摘要、校验或兼容老系统,它能用;但别拿它存密码。
为什么 md5() 不该用于密码存储
MD5 是确定性哈希,没有盐(salt),且已被大规模碰撞攻击破解。现代 PHP 应用中,password_hash() 才是正确选择。
- 相同输入永远输出相同
md5()值,彩虹表可直接反查常见口令 - 不支持加盐自动管理,手动拼接 salt 容易出错(比如
md5($salt . $pass)顺序错、编码不一致) - PHP 8.0+ 已标记
md5()为“不推荐用于安全敏感场景”,文档明确写明“not suitable for password hashing”
md5() 的正确使用场景和写法
它适合做快速校验(如文件完整性比对)、生成短标识符(如缓存 key)、或对接遗留接口要求 MD5 格式响应。
- 输入必须是字符串:二进制数据要先用
bin2hex()或确保 UTF-8 编码,否则中文可能被截断 - 默认返回 32 字符小写十六进制字符串;加第二个参数
true返回原始 16 字节二进制,慎用——很多地方会误当成乱码处理 - 注意空格和换行:读取文件用
file_get_contents()后直接传入,别用trim(),否则校验失败
示例:
立即学习“PHP免费学习笔记(深入)”;
echo md5("hello"); // 输出:5d41402abc4b2a76b9719d911017c592校验文件:
if (md5_file("/path/to/file.zip") === "a1b2c3...") { /* OK */ }和 hash() 函数对比有什么区别
md5() 是 hash() 的快捷封装,功能完全重叠,但 hash() 更灵活、更明确。
-
hash("md5", $data)和md5($data)结果一致,但前者支持更多算法(如"sha256"),便于后期替换 -
hash()支持$options参数控制输出格式(如是否输出二进制),md5()只有两个参数,扩展性差 - 某些 SAPI(如 HHVM 旧版)对
md5()有额外优化,但现代 PHP 中性能差异可忽略
容易被忽略的坑:编码、大小写、长度
看似简单,实际线上故障常出在这三处。
- PHP 默认按字节算哈希,
"中文"在 UTF-8 下是 6 字节,在 GBK 下是 4 字节——前后端编码不一致,md5()值就不同 - 有些 API 文档写的是“MD5 大写”,但 PHP
md5()永远小写,需手动strtoupper() -
md5_file()对大文件会吃内存,超 2GB 文件建议用hash_file("md5", $path)流式计算,更稳
真正难的从来不是调用函数,而是确认上下游约定的编码、大小写、是否含 BOM、换行符是 \n 还是 \r\n——这些细节不核对清楚,md5() 算得再快也没用。











