前端实现 MD5 加密
在前端开发中,经常需要对用户输入或敏感数据进行哈希处理,以增强安全性和完整性校验。MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希算法,可以将任意长度的数据转换为 128 位(32 字符)的十六进制字符串。
一、引入 CryptoJS 库
使用CryptoJS:https://github.com/brix/crypto-js 可以在浏览器端轻松完成 MD5 计算。首先在页面中通过 CDN 引入该库:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>MD5 示例</title><script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/crypto-js.min.js"></script>
</head>
<body><div><input type="text" id="inputText" placeholder="请输入需加密内容" /><button id="btnHash">生成MD5</button><p>结果:<span id="result"></span></p></div><script>const inputText = document.getElementById('inputText');const btnHash = document.getElementById('btnHash');const result = document.getElementById('result');btnHash.addEventListener('click', () => {const value = inputText.value;const hash = CryptoJS.MD5(value).toString();result.textContent = hash;});</script>
</body>
</html>
二、纯 JavaScript 实现
如果不想依赖外部库,也可以使用纯 JavaScript 实现 MD5 算法。以下示例为精简版实现:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>纯 JS MD5</title>
</head>
<body><div><input id="inputText" /><button id="btnHash">生成MD5</button><p>结果:<span id="result"></span></p></div><script>function md5cycle(x, k) {let a = x[0], b = x[1], c = x[2], d = x[3];function ff(a, b, c, d, x, s, t) {a = (a + ((b & c) | (~b & d)) + x + t) | 0;return ((a << s) | (a >>> (32 - s))) + b | 0;}function gg(a, b, c, d, x, s, t) {a = (a + ((b & d) | (c & ~d)) + x + t) | 0;return ((a << s) | (a >>> (32 - s))) + b | 0;}function hh(a, b, c, d, x, s, t) {a = (a + (b ^ c ^ d) + x + t) | 0;return ((a << s) | (a >>> (32 - s))) + b | 0;}function ii(a, b, c, d, x, s, t) {a = (a + (c ^ (b | ~d)) + x + t) | 0;return ((a << s) | (a >>> (32 - s))) + b | 0;}a = ff(a, b, c, d, k[0], 7, -680876936);d = ff(d, a, b, c, k[1], 12, -389564586);c = ff(c, d, a, b, k[2], 17, 606105819);b = ff(b, c, d, a, k[3], 22, -1044525330);a = gg(a, b, c, d, k[1], 5, -165796510);d = gg(d, a, b, c, k[6], 9, -1069501632);c = gg(c, d, a, b, k[11], 14, 643717713);b = gg(b, c, d, a, k[0], 20, -373897302);a = hh(a, b, c, d, k[5], 4, -378558);d = hh(d, a, b, c, k[8], 11, -2022574463);c = hh(c, d, a, b, k[11], 16, 1839030562);b = hh(b, c, d, a, k[14], 23, -35309556);a = ii(a, b, c, d, k[0], 6, -198630844);d = ii(d, a, b, c, k[7], 10, 1126891415);c = ii(c, d, a, b, k[14], 15, -1416354905);b = ii(b, c, d, a, k[5], 21, -57434055);x[0] = x[0] + a | 0;x[1] = x[1] + b | 0;x[2] = x[2] + c | 0;x[3] = x[3] + d | 0;}function md5blk(str) {const md5blks = [];for (let i = 0; i < 64; i += 4) {md5blks[i >> 2] = str.charCodeAt(i)+ (str.charCodeAt(i + 1) << 8)+ (str.charCodeAt(i + 2) << 16)+ (str.charCodeAt(i + 3) << 24);}return md5blks;}function md51(str) {const n = str.length;const state = [1732584193, -271733879, -1732584194, 271733878];let i;for (i = 64; i <= n; i += 64) {md5cycle(state, md5blk(str.slice(i - 64, i)));}str = str.slice(i - 64);const tail = Array(16).fill(0);for (i = 0; i < str.length; i++) {tail[i >> 2] |= str.charCodeAt(i) << ((i % 4) << 3);}tail[i >> 2] |= 0x80 << ((i % 4) << 3);if (i > 55) {md5cycle(state, tail);tail.fill(0);}tail[14] = n * 8;md5cycle(state, tail);return state;}function rhex(n) {let s = '';for (let j = 0; j < 4; j++) {s += ('0' + ((n >> (j * 8 + 4)) & 0x0F).toString(16)).slice(-2)+ ('0' + ((n >> (j * 8)) & 0x0F).toString(16)).slice(-2);}return s;}function md5(str) {const arr = md51(str);return arr.map(rhex).join('');}const input = document.getElementById('inputText');const button = document.getElementById('btnHash');const output = document.getElementById('result');button.addEventListener('click', () => {output.textContent = md5(input.value);});</script>
</body>
</html>