MD5(Message Digest Algorithm 5)雖不再適合密碼學安全場景,但在數據完整性校驗、緩存鍵生成、非敏感指紋等領域仍廣泛使用。跨語言/數據庫環境下,大小寫一致性是最大坑:Java/MySQL/JS 默認小寫十六進制,Oracle 官方包返回大寫。
驗證向量:
md5("1") = c4ca4238a0b923820dcc509a6f75849b
md5(md5("1")) = 28c8edde3d61a0411511d3b1866f0636
public class MD5Util {
public static String md5(String plainText) {
if (plainText == null) plainText = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(plainText.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder(32);
for (byte b : digest) {
sb.append(String.format("%02x", b)); // 自動補零、小寫
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("MD5 algorithm not available", e);
}
}
}
SELECT MD5('1') AS m1, MD5(MD5('1')) AS m2;
/* 結果均為小寫:
m1: c4ca4238a0b923820dcc509a6f75849b
m2: 28c8edde3d61a0411511d3b1866f0636 */
// 核心邏輯:RFC 1321 標準實現,輸出小寫十六進制
const md5 = (function() {
// ... 完整算法實現(文中提供完整代碼)...
return function(text) { return hex_md5(text); };
})();
// 使用
console.log(md5("1")); // c4ca4238a0b923820dcc509a6f75849b
console.log(md5(md5("1"))); // 28c8edde3d61a0411511d3b1866f0636
生產建議:前端用 crypto-js、spark-md5 等成熟庫,支持流式/WebWorker;Node.js 用內建 crypto.createHash('md5')。
CREATE OR REPLACE FUNCTION MD5(passwd IN VARCHAR2) RETURN VARCHAR2 IS
retval VARCHAR2(32);
BEGIN
-- DBMS_OBFUSCATION_TOOLKIT 返回 RAW,轉十六進制後為大寫
retval := LOWER(RAWTOHEX(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => passwd)));
RETURN retval;
END;
/
SELECT MD5('1') AS m1, MD5(MD5('1')) AS m2 FROM dual;
/* 結果與 Java/MySQL/JS 完全一致 */
| 環境 | 默認大小寫 | 處理建議 |
|---|---|---|
| Java (MessageDigest) | 小寫 | 直接用 |
| MySQL MD5() | 小寫 | 直接用 |
| JavaScript (crypto-js等) | 小寫 | 直接用 |
| Oracle DBMS_OBFUSCATION_TOOLKIT | 大寫 | 必須 LOWER() |
| Python hashlib.md5().hexdigest() | 小寫 | 直接用 |
| Go md5.Sum() | 小寫 | fmt.Printf("%x") |
| .NET MD5.ComputeHash() | 小寫 | BitConverter.ToString().Replace("-","").ToLower() |