一句话总结:
Base64 是“快递打包术”,把二进制数据变成字符串方便传输;MD5 是“指纹生成器”,把数据压缩成唯一指纹(但已过时,不够安全)。
Base64 —— 数据“快递打包”
1. 作用
把二进制数据(如图片、文件)转换成可打印的字符串,方便在文本协议(如 JSON、XML)中传输。
2. 使用场景
- 上传图片到服务器(转成 Base64 字符串嵌入 JSON)。
- 加密后的二进制数据(如 AES 加密结果)转字符串存储。
3. 代码示例(Kotlin)
// 编码
val data = "Hello".toByteArray()
val base64Str = Base64.encodeToString(data, Base64.DEFAULT)
println(base64Str) // SGVsbG8=
// 解码
val decodedData = Base64.decode(base64Str, Base64.DEFAULT)
println(String(decodedData)) // Hello
4. 注意
- 不是加密!Base64 只是编码,任何人都可以轻松解码,不能用于加密敏感数据。
- 体积会膨胀约 33%(每 3 字节变 4 字符)。
MD5 —— 数据“指纹生成”
1. 作用
将任意数据(如文件、密码)计算出一个固定长度(32位)的哈希值,用于校验数据完整性或生成唯一标识。
2. 使用场景
- 校验文件是否被篡改(对比下载文件的 MD5 和官方提供的 MD5)。
- 旧系统密码存储(但已过时,不安全!)。
3. 代码示例(Kotlin)
fun md5(input: String): String {
val md = MessageDigest.getInstance("MD5")
val digest = md.digest(input.toByteArray())
return digest.toHex() // 转成16进制字符串
}
// 扩展函数:字节数组转16进制
fun ByteArray.toHex() = joinToString("") { "%02x".format(it) }
// 使用
println(md5("Hello")) // 8b1a9953c4611296a827abf8c47804d7
4. 注意
- 已不推荐用于密码存储!MD5 容易通过“彩虹表”破解,需加盐(Salt)或改用更安全的哈希算法(如 SHA-256、BCrypt)。
- 无法逆向解密:MD5 是单向哈希,无法从哈希值还原原始数据。
- 碰撞风险:不同数据可能生成相同 MD5(已被证明不安全)。
对比总结
| 特性 | Base64 | MD5 |
|---|---|---|
| 用途 | 数据编码(方便传输) | 生成数据指纹(校验完整性) |
| 是否可逆 | 可逆(能解码还原原始数据) | 不可逆(无法从哈希值还原数据) |
| 安全性 | 无加密作用 | 已不安全,需结合盐值或更高级算法 |
| 输出长度 | 随输入数据增长 | 固定 32 位(16进制)或 16 字节 |
实际场景建议
-
Base64:
- 网络传输二进制数据(如图片转字符串)。
- 避免用于敏感数据(如密码、密钥)的直接编码。
-
MD5:
- 仅用于非敏感场景(如文件校验、缓存 Key 生成)。
- 密码存储必须加盐,并改用 SHA-256 + BCrypt!
安全警告(避坑指南)
-
MD5 不要单独用于密码存储:
// 错误做法(危险!) fun savePassword(password: String) { val hashed = md5(password) // 存储到数据库... } // 正确做法(使用 BCrypt) fun savePassword(password: String) { val salt = BCrypt.gensalt() val hashed = BCrypt.hashpw(password, salt) // 存储到数据库... } -
Base64 不是加密:敏感数据需先加密(如 AES)再 Base64 编码。
总结口诀
“Base64 是快递员,二进制转字符串传,
可逆编码非加密,敏感数据别偷懒。
MD5 生成指纹串,校验文件能防篡,
密码存储已过时,加盐升级更安全!”