MD5 (Message Digest Algorithm 5) 廣泛用於密碼雜湊、資料完整性驗證、快取鍵值生成等場景。但在 Java、JavaScript、MySQL、Oracle 等不同環境下實作時,常因大小寫差異、編碼方式、輸出格式 不一致導致驗證失敗。本文提供四大平台統一輸出小寫十六進制字串的標準實作,確保跨系統一致性。
c4ca4238a0b923820dcc509a6f75849b)import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
public class MD5Util {
/**
* 計算字串 MD5,回傳 32 位小寫十六進制字串
*/
public static String md5(String input) {
if (input == null) input = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder(32);
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 算法不可用", e);
}
}
// 測試
public static void main(String[] args) {
String s1 = md5("1");
String s2 = md5(s1); // 雙重 MD5
System.out.println("md5('1') = " + s1);
System.out.println("md5(md5('1')) = " + s2);
// 輸出:
// md5('1') = c4ca4238a0b923820dcc509a6f75849b
// md5(md5('1')) = 28c8edde3d61a0411511d3b1866f0636
}
}
MySQL 內建 MD5() 函數直接回傳小寫十六進制字串,完全符合標準:
-- 單次 MD5
SELECT MD5('1') AS m1;
-- 結果: c4ca4238a0b923820dcc509a6f75849b
-- 雙重 MD5 (注意: 內層結果已是小寫字串)
SELECT MD5(MD5('1')) AS m2;
-- 結果: 28c8edde3d61a0411511d3b1866f0636
-- 實務應用: 密碼雜湊儲存
INSERT INTO users (username, password_hash)
VALUES ('admin', MD5(CONCAT('salt_', 'user_password')));
推薦使用 blueimp/JavaScript-MD5 (約 3KB gzipped),支援 AMD/CommonJS/全域變數:
<script src="https://cdn.jsdelivr.net/npm/blueimp-md5@2.19.0/js/md5.min.js"></script>
<script>
// 單次 MD5
console.log(md5("1"));
// c4ca4238a0b923820dcc509a6f75849b
// 雙重 MD5
console.log(md5(md5("1")));
// 28c8edde3d61a0411511d3b1866f0636
// Node.js 環境
// const md5 = require('blueimp-md5');
Node.js 原生實作 (無外部依賴):
const crypto = require('crypto');
function md5(str) {
return crypto.createHash('md5').update(str, 'utf8').digest('hex');
}
console.log(md5("1")); // c4ca4238a0b923820dcc509a6f75849b
console.log(md5(md5("1"))); // 28c8edde3d61a0411511d3b1866f0636
Oracle DBMS_OBFUSCATION_TOOLKIT.MD5 回傳大寫 RAW 型別,需轉換為小寫字串:
-- 建立包裝函數回傳標準小寫 VARCHAR2
CREATE OR REPLACE FUNCTION MD5_LOWER(p_text IN VARCHAR2) RETURN VARCHAR2 IS
v_raw RAW(16);
v_hex VARCHAR2(32);
BEGIN
v_raw := DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => p_text);
v_hex := LOWER(RAWTOHEX(v_raw));
RETURN v_hex;
END;
/
-- 測試
SELECT MD5_LOWER('1') AS m1, MD5_LOWER(MD5_LOWER('1')) AS m2 FROM dual;
-- M1: c4ca4238a0b923820dcc509a6f75849b
-- M2: 28c8edde3d61a0411511d3b1866f0636
| 輸入 | Java | MySQL | JavaScript | Oracle (包裝後) |
|---|---|---|---|---|
md5("1") | c4ca4238a0b923820dcc509a6f75849b | c4ca4238a0b923820dcc509a6f75849b | c4ca4238a0b923820dcc509a6f75849b | c4ca4238a0b923820dcc509a6f75849b |
md5(md5("1")) | 28c8edde3d61a0411511d3b1866f0636 | 28c8edde3d61a0411511d3b1866f0636 | 28c8edde3d61a0411511d3b1866f0636 | 28c8edde3d61a0411511d3b1866f0636 |
md5("hello") | 5d41402abc4b2a76b9719d911017c592 | 5d41402abc4b2a76b9719d911017c592 | 5d41402abc4b2a76b9719d911017c592 | 5d41402abc4b2a76b9719d911017c592 |