一、引入外部库CryptoJS(简单)
1、字符串Hash
<!DOCTYPE html>
<html>
<head>
<title>Hash算法</title>
<script type="text/javascript" src="CryptoJS-3.1.2/rollups/md5.js"></script>
<script type="text/javascript" src="CryptoJS-3.1.2/rollups/sha1.js"></script>
<script type="text/javascript" src="CryptoJS-3.1.2/rollups/sha256.js"></script>
<script type="text/javascript" src="CryptoJS-3.1.2/rollups/hmac-sha1.js"></script>
<script type="text/javascript" src="CryptoJS-3.1.2/rollups/hmac-sha256.js"></script>
</head>
<body>
<script type="text/javascript">
// ======================== Hash算法 ========================
console.log('MD5:', CryptoJS.MD5("abc").toString());
console.log('SHA1:', CryptoJS.SHA1("abc").toString());
console.log('SHA256:', CryptoJS.SHA256("abc").toString());
console.log('hmac-sha1:', CryptoJS.HmacSHA1("abc", "123").toString());
console.log('hmac-sha256:', CryptoJS.HmacSHA256("abc", "123").toString());
</script>
</body>
</html>
2、文件Hash
<!DOCTYPE html>
<html>
<head>
<title>Hash算法</title>
<script type="text/javascript" src="CryptoJS-3.1.2/rollups/md5.js"></script>
</head>
<body>
<script type="text/javascript">
window.onload = function () {
function fileMd5Sum(file) {
const fileReader = new FileReader();
fileReader.onloadend = (ev) => {
const md5 = CryptoJS.MD5(CryptoJS.enc.Latin1.parse(ev.target.result)).toString(CryptoJS.enc.Hex);
console.log(md5);
}
fileReader.readAsBinaryString(file);
}
// 获取文件
let file = document.getElementById("file");
file.addEventListener("change", function () {
fileMd5Sum(file.files[0]);
})
}
</script>
<input type="file" id="file"/>
</body>
</html>
3、参考
CryptoJS常用的加密算法使用及原理
https://blog.csdn.net/qq_21531681/article/details/108608131
二、不引入外部库(复杂)
【注意】要求https访问才可以使用。
1、字符串Hash
const content2 = '这是用来计算SHA-256的字符串的方法';
async function digestMessage(message) {
const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8); // hash the message
const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
return hashHex;
}
digestMessage(content2)
.then(digestHex => console.log(digestHex));
参考:
vue/js通过计算 字符串 / 文件 sha1(SHA-1)值、sha256值等方法
https://blog.csdn.net/weixin_42634991/article/details/124601829
2、文件Hash
三种方法计算Hash
值的方法都是相同的;只是将Hash
值转换为16进制
或base 64
不同。
(1)方法一
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
window.onload = function () {
let file = document.getElementById("fileid");
file.addEventListener("change", function () {
let read = new FileReader();
read.readAsArrayBuffer(file.files[0])
read.onload = function () {
(async function () {
//let inputBytes = new TextEncoder().encode("hello world");
let sha1 = await crypto.subtle.digest('SHA-1', read.result).then(a => Array.from(new Uint8Array(a)).map(a => a.toString(16).padStart(2, '0')).join(""));
console.log(sha1);
})();
}
})
}
</script>
</head>
<body>
<input type="file" id="fileid">
</body>
</html>
参考:
不用引入外部库,在浏览器上一行计算出SHA-1/SHA-256的结果
https://blog.csdn.net/emu/article/details/121862519
(2)方法二
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
window.onload = function () {
/**
* 获取16进制摘要字符串
* @param buffer
* @returns {string}
*/
function hex(buffer) {
let code = [];
let view = new DataView(buffer);
for (var i = 0; i < view.byteLength; i += 4) {
value = view.getUint32(i)
let stringValue = value.toString(16)
// 填充切片
let padding = '00000000'
let paddedValue = (padding + stringValue).slice(-padding.length)
code.push(paddedValue);
}
return code.join("");
}
/**
* 获取文件,计算hash
* @type {HTMLElement}
*/
let file = document.getElementById("fileid");
file.addEventListener("change", function () {
let read = new FileReader();
read.readAsArrayBuffer(file.files[0])
read.onload = function () {
(async function () {
let arr = await crypto.subtle.digest('SHA-256', read.result);
//console.log(arr);
//调用函数,获取16进制摘要字符串
let sha256Msg = hex(arr);
console.log(sha256Msg);
})();
}
})
}
</script>
</head>
<body>
<input type="file" id="fileid">
</body>
</html>
参考:
javascript获取文件sha-256,sha-384,sha-512摘要,验证文件是否被篡改,验证文件一致性,文件安全管理,计算文件的MD5值
https://blog.csdn.net/qq_41974199/article/details/124232425
(3)方法三
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
window.onload = function () {
// from: https://stackoverflow.com/a/40031979/9014097
function buf2hex(buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
// from https://stackoverflow.com/a/11562550/9014097
function buf2Base64(buffer) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)));
}
/**
* 获取文件,计算hash
* @type {HTMLElement}
*/
let file = document.getElementById("fileid");
file.addEventListener("change", function () {
let read = new FileReader();
read.readAsArrayBuffer(file.files[0])
read.onload = function () {
(async function () {
let hashBytes = await window.crypto.subtle.digest("SHA-256", read.result);
console.log(JSON.stringify({hash: buf2hex(hashBytes)})); // {"hash":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"}
console.log(JSON.stringify({hash: buf2Base64(hashBytes)})); // {"hash":"16j7swfXgJRpypq8sAguT41WUeRtPNt2LQLQvzfJ5ZI="}
})();
}
})
}
</script>
</head>
<body>
<input type="file" id="fileid">
</body>
</html>
3、参考资料
为什么crypto.subtle.digest返回一个空对象
https://cloud.tencent.com/developer/ask/sof/767149