Js原生md5加密
直接引入
// 用于计算MD5的常量表
const MD5_CONSTANT_TABLE = [
0x07, 0x12, 0x17, 0x93, 0x29, 0x3d, 0xca, 0xde,
0x5b, 0x5e, 0x6d, 0x70, 0x98, 0x9c, 0xaf, 0xb0,
0xbd, 0xd3, 0xe0, 0xf3, 0x10d, 0x136, 0x146, 0x168,
0x199, 0x1bd, 0x1c3, 0x1d2, 0x277, 0x28d, 0x298, 0x2b0,
0x2c5, 0x2f2, 0x323, 0x32e, 0x340, 0x3f7, 0x425, 0x44c,
0x461, 0x4cc, 0x4ea, 0x513, 0x56f, 0x5b6, 0x5f1, 0x62c,
0x644, 0x6a6, 0x6d3, 0x6de, 0x6f0, 0x718, 0x732, 0x74f,
0x77a, 0x7a7, 0x7e4, 0x7f0, 0x800, 0x819, 0x853, 0x85f
];
// 用于计算MD5的变化表
const MD5_CHANGE_TABLE = [
[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15],
[ 1, 6, 11, 0], [ 5, 10, 15, 4], [ 9, 14, 3, 8], [13, 2, 7, 12],
[ 5, 8, 11, 14], [ 1, 4, 7, 10], [13, 0, 3, 6], [ 9, 12, 15, 2],
[ 0, 7, 14, 5], [10, 13, 4, 15], [ 6, 9, 8, 11], [ 3, 2, 12, 1]
];
/**
* 将一个二进制数转换为16进制字符串
* @param {number} byte - 二进制数
* @returns {string} 16进制字符串
* @private
*/
function _byteToHex(byte) {
return byte < 16 ? '0' + byte.toString(16) : byte.toString(16);
}
/**
* 将一个字节数组转换为16进制字符串
* @param {Array<number>} bytes - 字节数组
* @returns {string} 16进制字符串
* @private
*/
function _bytesToHex(bytes) {
return bytes.map(_byteToHex).join('');
}
/**
* 在字符串末尾填充bit位的0,使其长度为length的倍数
* @param {string} str - 原始字符串
* @param {number} bit - 每次填充的位数
* @param {number} length - 填充后字符串的长度
* @returns {string} 填充后的字符串
* @private
*/
function _pad(str, bit, length) {
let targetLength = length * bit;
let padLength = targetLength - str.length;
if (padLength < 0) {
// 字符串已经足够长,无需填充
return str;
}
let padStr = '';
while (padLength--) {
padStr += '0';
}
return str + padStr;
}
/**
* 对字符串进行MD5加密
* @param {string} data - 待加密的字符串
* @returns {string} 加密后的字符串(16进制)
*/
function md5(data) {
// 将字符串转换为UTF8的二进制数组
let utf8Bytes = unescape(encodeURIComponent(data))
.split('')
.map(char => char.charCodeAt(0));
let length = utf8Bytes.length * 8; // 字符串长度
utf8Bytes.push(0x80); // 添加一个1
let padLength = Math.ceil((utf8Bytes.length * 8 + 64) / 512) * 16 - utf8Bytes.length;// 填充长度(字节数)
for (let i = 0; i < padLength; i++) {
utf8Bytes.push(0x00);
}
let bitLength = length.toString(2).split('');
bitLength = _pad(bitLength, 1, 64).split('');// 将长度转换为64位的二进制数
bitLength.forEach(bit => utf8Bytes.push(parseInt(bit, 2))); // 将长度添加到末尾
let a = 0x67452301;
let b = 0xefcdab89;
let c = 0x98badcfe;
let d = 0x10325476;
let chunks = [];
// 将每个512位(64字节)的块分成16个32位(4字节)的小块
for (let i = 0, len = utf8Bytes.length; i < len; i += 64) {
chunks.push(utf8Bytes.slice(i, i + 64));
}
// 对每个小块进行处理
for (let i = 0, len = chunks.length; i < len; i++) {
let [ A, B, C, D ] = [ a, b, c, d ];
let chunk = chunks[i];
// 循环64次进行加密
for (let j = 0; j < 64; j++) {
let f, g;
if (j < 16) {
f = (B & C) | ((~B) & D);
g = j;
} else if (j < 32) {
f = (D & B) | ((~D) & C);
g = (5 * j + 1) % 16;
} else if (j < 48) {
f = B ^ C ^ D;
g = (3 * j + 5) % 16;
} else {
f = C ^ (B | (~D));
g = (7 * j) % 16;
}
let index1 = MD5_CHANGE_TABLE[j][0];
let index2 = MD5_CHANGE_TABLE[j][1];
let index3 = MD5_CHANGE_TABLE[j][2];
let index4 = MD5_CHANGE_TABLE[j][3];
let x = chunk[index4] << 24 | chunk[index3] << 16 | chunk[index2] << 8 | chunk[index1];
let y = (f + A + MD5_CONSTANT_TABLE[j] + x) & 0xffffffff;
A = D;
D = C;
C = B;
B = (B + (y << g | y >>> (32 - g))) & 0xffffffff;
}
a = (a + A) & 0xffffffff;
b = (b + B) & 0xffffffff;
c = (c + C) & 0xffffffff;
d = (d + D) & 0xffffffff;
}
let result = [ a, b, c, d ]
.map(num => _pad(num.toString(2), 8, 4)) // 将数字转换为二进制字符串,并补齐到32位
.join(''); // 将四个32位二进制字符串拼接
return _bytesToHex(result.match(/\d{8}/g).map(byte => parseInt(byte, 2))); // 将二进制字符串转换为16进制字符串
}
// 使用
md5(加密内容)
npm导入
npm i --save js-md5
// 全局定义
import md5 from 'js-md5'
Vue.prototype.$md5 = md5
// 使用方法
this.$md5(加密内容)
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。