JS实现md5加密

<script>
        function md5(str) {
            const encoder = new TextEncoder();
            const data = Array.from(encoder.encode(str));
            let len = data.length;
            const bits = len * 8;

            // 填充数据
            data.push(0x80);
            while ((data.length * 8) % 512 !== 448) {
                data.push(0x00);
            }

            // 添加小端序的长度
            const lenLow = bits >>> 0;
            const lenHigh = Math.floor(bits / 0x100000000) >>> 0;
            for (let i = 0; i < 4; i++) {
                data.push((lenLow >>> (i * 8)) & 0xff);
            }
            for (let i = 0; i < 4; i++) {
                data.push((lenHigh >>> (i * 8)) & 0xff);
            }

            // 初始化哈希值
            let h0 = 0x67452301;
            let h1 = 0xefcdab89;
            let h2 = 0x98badcfe;
            let h3 = 0x10325476;

            // 处理每个512位块
            for (let i = 0; i < data.length; i += 64) {
                const chunk = data.slice(i, i + 64);
                const X = new Array(16);
                for (let j = 0; j < 16; j++) {
                    X[j] = (
                        chunk[j * 4] |
                        chunk[j * 4 + 1] << 8 |
                        chunk[j * 4 + 2] << 16 |
                        chunk[j * 4 + 3] << 24
                    ) >>> 0;
                }

                let [a, b, c, d] = [h0, h1, h2, h3];

                // 定义轮次参数
                const K = Array.from({ length: 64 }, (_, i) => {
                    return Math.floor(Math.abs(Math.sin(i + 1)) * 0x100000000) >>> 0;
                });
                const r = [
                    7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
                    5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
                    4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
                    6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
                ];

                for (let i = 0; i < 64; i++) {
                    let f, g;
                    if (i < 16) {
                        f = (b & c) | (~b & d);
                        g = i;
                    } else if (i < 32) {
                        f = (d & b) | (~d & c);
                        g = (5 * i + 1) % 16;
                    } else if (i < 48) {
                        f = b ^ c ^ d;
                        g = (3 * i + 5) % 16;
                    } else {
                        f = c ^ (b | ~d);
                        g = (7 * i) % 16;
                    }

                    f = (f + a + K[i] + X[g]) >>> 0;
                    f = ((f << r[i]) | (f >>> (32 - r[i]))) >>> 0;
                    f = (f + b) >>> 0;

                    // 轮换变量
                    [a, b, c, d] = [d, f, b, c];
                }

                // 更新哈希值
                h0 = (h0 + a) >>> 0;
                h1 = (h1 + b) >>> 0;
                h2 = (h2 + c) >>> 0;
                h3 = (h3 + d) >>> 0;
            }

            // 转换为小端序的十六进制字符串
            const result = new Uint8Array(16);
            const view = new DataView(result.buffer);
            view.setUint32(0, h0, true);
            view.setUint32(4, h1, true);
            view.setUint32(8, h2, true);
            view.setUint32(12, h3, true);
            return Array.from(result).map(b => b.toString(16).padStart(2, '0')).join('');
        }
    </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值