js实现sha1
SHA-1 简介
SHA-1(Secure Hash Algorithm 1)是一种哈希函数,用于生成160位的哈希值。虽然现在已被认为不够安全,但在某些场景仍有使用需求。
浏览器端实现
现代浏览器原生支持crypto API,可以直接计算SHA-1:
async function sha1(message) {
const encoder = new TextEncoder();
const data = encoder.encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-1', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex;
}
// 使用示例
sha1('hello world').then(console.log); // 输出: 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
Node.js 实现
Node.js内置crypto模块:
const crypto = require('crypto');
function sha1(str) {
return crypto.createHash('sha1').update(str).digest('hex');
}
console.log(sha1('hello world')); // 输出: 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
纯JavaScript实现
以下是一个完整的SHA-1算法实现(不依赖任何库):
function sha1(message) {
function rotateLeft(n, s) {
return (n << s) | (n >>> (32 - s));
}
function toHex(value) {
let hex = '';
for (let i = 7; i >= 0; i--) {
hex += ((value >> (i * 4)) & 0xf).toString(16);
}
return hex;
}
const H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
const K = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];
message = unescape(encodeURIComponent(message));
const length = message.length;
const words = [];
for (let i = 0; i < length - 3; i += 4) {
words.push(
message.charCodeAt(i) << 24 |
message.charCodeAt(i + 1) << 16 |
message.charCodeAt(i + 2) << 8 |
message.charCodeAt(i + 3)
);
}
switch (length % 4) {
case 0: i = 0x080000000; break;
case 1: i = message.charCodeAt(length - 1) << 24 | 0x0800000; break;
case 2: i = message.charCodeAt(length - 2) << 24 | message.charCodeAt(length - 1) << 16 | 0x08000; break;
case 3: i = message.charCodeAt(length - 3) << 24 | message.charCodeAt(length - 2) << 16 | message.charCodeAt(length - 1) << 8 | 0x80; break;
}
words.push(i);
while (words.length % 16 !== 14) {
words.push(0);
}
words.push(length >>> 29);
words.push((length << 3) & 0x0ffffffff);
for (let block = 0; block < words.length; block += 16) {
const W = new Array(80);
for (let t = 0; t < 16; t++) {
W[t] = words[block + t];
}
for (let t = 16; t < 80; t++) {
W[t] = rotateLeft(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
}
let [a, b, c, d, e] = H;
for (let t = 0; t < 80; t++) {
let s = Math.floor(t / 20);
let f, k;
switch (s) {
case 0: f = (b & c) | (~b & d); k = K[0]; break;
case 1: f = b ^ c ^ d; k = K[1]; break;
case 2: f = (b & c) | (b & d) | (c & d); k = K[2]; break;
case 3: f = b ^ c ^ d; k = K[3]; break;
}
const temp = (rotateLeft(a, 5) + f + e + k + W[t]) >>> 0;
e = d;
d = c;
c = rotateLeft(b, 30);
b = a;
a = temp;
}
H[0] = (H[0] + a) >>> 0;
H[1] = (H[1] + b) >>> 0;
H[2] = (H[2] + c) >>> 0;
H[3] = (H[3] + d) >>> 0;
H[4] = (H[4] + e) >>> 0;
}
return H.map(toHex).join('').toLowerCase();
}
console.log(sha1('hello world')); // 输出: 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
注意事项
- 浏览器端实现需要HTTPS环境或localhost才能使用crypto.subtle
- Node.js实现是最高效的方式
- 纯JavaScript实现主要用于学习目的,性能不如原生API
- SHA-1已被证明存在安全漏洞,重要场景应考虑使用SHA-256或SHA-3







