#define 常數 | final static 欄位 (類別層級共享) |
| 計算巨集 (宏) | private final static 方法 |
unsigned long (32-bit) | Java int 為有符號 32-bit,位運算結果相同;但無符號右移需用 >>>> |
| 32-bit 無符號加法溢位 | Java int 加法會產生負數,關鍵變數改用 long (64-bit) 承接,最後取低 32-bit |
| 位旋轉 | 手動實現 rotateLeft(x, n) = (x << n) | (x >>> (32-n)) |
核心類別結構
package beartool;
public class MD5 {
// RFC 1321 常數 S11..S44, T[64] 等 -> final static
// 內部狀態: long[] state = new long[4]; long[] count = new long[2]; byte[] buffer = new byte[64];
// 公有 API:
// public MD5() { reset(); }
// public void update(byte[] input) / update(byte[] input, int offset, int len)
// public byte[] finalize() // 產生 16 位元組 digest
// public String toHexString() // 32 字元十六進位字串
// 私有核心: transform(long[] block), encode/decode byte<->long, rotateLeft, FF/GG/HH/II 函數
}
標準測試套件驗證 (RFC 1321)
MD5("") = d41d8cd98f00b204e9800998ecf8427e
MD5("a") = 0cc175b9c0f1b6a831c399e269772661
MD5("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
編譯執行 java beartool.MD5 "test string" 輸出與標準套件完全一致。
跨平台驗證
將 MD5.class 複製至 Linux + IBM JDK 1.3 執行,結果完全一致,確認「一次編寫到處運行」。
效能觀測
肉眼感知 Java 版 MD5 計算「一閃即成」,未覺明顯較 C 版慢 (JIT 編譯優化熱點路徑)。
應用:使用者密碼 MD5 保護
// 註冊/修改密碼
String pwdMD5 = new MD5().update(password.getBytes("UTF-8")).toHexString();
dao.saveUser(username, pwdMD5); // 資料庫儲存 MD5,不存明文
// 登入驗證
String inputMD5 = new MD5().update(inputPwd.getBytes("UTF-8")).toHexString();
String storedMD5 = dao.getPasswordMD5(username);
if (inputMD5.equals(storedMD5)) loginSuccess();
優勢:開發者/DBA 無法從資料庫讀取明文密碼;注意:需防範彩虹表攻擊 (加鹽 Salt)、避免弱密碼、現代建議改用 BCrypt/Argon2/SCrypt。
Java Bean 部署
- 編譯:
javac -d . MD5.java → 產生 beartool/MD5.class
- 使用:
import beartool.MD5; 實例化調用。
- 打包:保持
beartool/MD5.class 相對路徑置入 JAR/WAR。
- 上一篇文章: XML 轉 JavaBean 並持久化:半自動解析框架設計
- 下一篇文章: EJB Session Bean 規範與限制完整指南 (實現介面、方法命名、異常處理)
Copyright ©
程式碼之家 All Rights Reserved