如何在客户端JavaScript自动生成远程图片的MD5校验值?
实现远程图片MD5校验与更新检测
下面是直接可用的代码,替换了原参考代码的文件上传逻辑,改为自动请求远程图片并计算MD5,再与你预存的旧值对比:
// 复用参考代码中的MD5核心计算逻辑 function md5(arrayBuffer) { const uint8 = new Uint8Array(arrayBuffer); const words = []; for (let i = 0; i < uint8.length; i += 4) { words.push( (uint8[i] << 24) | (uint8[i + 1] << 16) | (uint8[i + 2] << 8) | uint8[i + 3] ); } const len = uint8.length * 8; words[len >> 5] |= 0x80 << len % 32; words[(((len + 64) >>> 9) << 4) + 14] = len; function rotateLeft(n, s) { return (n << s) | (n >>> (32 - s)); } function addUnsigned(a, b) { return (a + b) & 0xFFFFFFFF; } function md5cmn(q, a, b, x, s, t) { return addUnsigned(rotateLeft(addUnsigned(addUnsigned(a, q), addUnsigned(x, t)), s), b); } function md5ff(a, b, c, d, x, s, t) { return md5cmn((b & c) | (~b & d), a, b, x, s, t); } function md5gg(a, b, c, d, x, s, t) { return md5cmn((b & d) | (c & ~d), a, b, x, s, t); } function md5hh(a, b, c, d, x, s, t) { return md5cmn(b ^ c ^ d, a, b, x, s, t); } function md5ii(a, b, c, d, x, s, t) { return md5cmn(c ^ (b | ~d), a, b, x, s, t); } let a = 0x67452301; let b = 0xefcdab89; let c = 0x98badcfe; let d = 0x10325476; for (let i = 0; i < words.length; i += 16) { const olda = a; const oldb = b; const oldc = c; const oldd = d; a = md5ff(a, b, c, d, words[i], 7, 0xd76aa478); d = md5ff(d, a, b, c, words[i + 1], 12, 0xe8c7b756); c = md5ff(c, d, a, b, words[i + 2], 17, 0x242070db); b = md5ff(b, c, d, a, words[i + 3], 22, 0xc1bdceee); a = md5ff(a, b, c, d, words[i + 4], 7, 0xf57c0faf); d = md5ff(d, a, b, c, words[i + 5], 12, 0x4787c62a); c = md5ff(c, d, a, b, words[i + 6], 17, 0xa8304613); b = md5ff(b, c, d, a, words[i + 7], 22, 0xfd469501); a = md5ff(a, b, c, d, words[i + 8], 7, 0x698098d8); d = md5ff(d, a, b, c, words[i + 9], 12, 0x8b44f7af); c = md5ff(c, d, a, b, words[i + 10], 17, 0xffff5bb1); b = md5ff(b, c, d, a, words[i + 11], 22, 0x895cd7be); a = md5ff(a, b, c, d, words[i + 12], 7, 0x6b901122); d = md5ff(d, a, b, c, words[i + 13], 12, 0xfd987193); c = md5ff(c, d, a, b, words[i + 14], 17, 0xa679438e); b = md5ff(b, c, d, a, words[i + 15], 22, 0x49b40821); a = md5gg(a, b, c, d, words[i + 1], 5, 0xf61e2562); d = md5gg(d, a, b, c, words[i + 6], 9, 0xc040b340); c = md5gg(c, d, a, b, words[i + 11], 14, 0x265e5a51); b = md5gg(b, c, d, a, words[i], 20, 0xe9b6c7aa); a = md5gg(a, b, c, d, words[i + 5], 5, 0xd62f105d); d = md5gg(d, a, b, c, words[i + 10], 9, 0x02441453); c = md5gg(c, d, a, b, words[i + 15], 14, 0xd8a1e681); b = md5gg(b, c, d, a, words[i + 4], 20, 0xe7d3fbc8); a = md5gg(a, b, c, d, words[i + 9], 5, 0x21e1cde6); d = md5gg(d, a, b, c, words[i + 14], 9, 0xc33707d6); c = md5gg(c, d, a, b, words[i + 3], 14, 0xf4d50d87); b = md5gg(b, c, d, a, words[i + 8], 20, 0x455a14ed); a = md5gg(a, b, c, d, words[i + 13], 5, 0xa9e3e905); d = md5gg(d, a, b, c, words[i + 2], 9, 0xfcefa3f8); c = md5gg(c, d, a, b, words[i + 7], 14, 0x676f02d9); b = md5gg(b, c, d, a, words[i + 12], 20, 0x8d2a4c8a); a = md5hh(a, b, c, d, words[i + 5], 4, 0xfffa3942); d = md5hh(d, a, b, c, words[i + 8], 11, 0x8771f681); c = md5hh(c, d, a, b, words[i + 11], 16, 0x6d9d6122); b = md5hh(b, c, d, a, words[i + 14], 23, 0xfde5380c); a = md5hh(a, b, c, d, words[i + 1], 4, 0xa4beea44); d = md5hh(d, a, b, c, words[i + 4], 11, 0x4bdecfa9); c = md5hh(c, d, a, b, words[i + 7], 16, 0xf6bb4b60); b = md5hh(b, c, d, a, words[i + 10], 23, 0xbebfbc70); a = md5hh(a, b, c, d, words[i + 13], 4, 0x289b7ec6); d = md5hh(d, a, b, c, words[i], 11, 0xeaa127fa); c = md5hh(c, d, a, b, words[i + 3], 16, 0xd4ef3085); b = md5hh(b, c, d, a, words[i + 6], 23, 0x04881d05); a = md5hh(a, b, c, d, words[i + 9], 4, 0xd9d4d039); d = md5hh(d, a, b, c, words[i + 12], 11, 0xe6db99e5); c = md5hh(c, d, a, b, words[i + 15], 16, 0x1fa27cf8); b = md5hh(b, c, d, a, words[i + 2], 23, 0xc4ac5665); a = md5ii(a, b, c, d, words[i], 6, 0xf4292244); d = md5ii(d, a, b, c, words[i + 7], 10, 0x432aff97); c = md5ii(c, d, a, b, words[i + 14], 15, 0xab9423a7); b = md5ii(b, c, d, a, words[i + 5], 21, 0xfc93a039); a = md5ii(a, b, c, d, words[i + 12], 6, 0x655b59c3); d = md5ii(d, a, b, c, words[i + 3], 10, 0x8f0ccc92); c = md5ii(c, d, a, b, words[i + 10], 15, 0xffeff47d); b = md5ii(b, c, d, a, words[i + 1], 21, 0x85845dd1); a = md5ii(a, b, c, d, words[i + 8], 6, 0x6fa87e4f); d = md5ii(d, a, b, c, words[i + 15], 10, 0xfe2ce6e0); c = md5ii(c, d, a, b, words[i + 6], 15, 0xa3014314); b = md5ii(b, c, d, a, words[i + 13], 21, 0x4e0811a1); a = md5ii(a, b, c, d, words[i + 4], 6, 0xf7537e82); d = md5ii(d, a, b, c, words[i + 11], 10, 0xbd3af235); c = md5ii(c, d, a, b, words[i + 2], 15, 0x2ad7d2bb); b = md5ii(b, c, d, a, words[i + 9], 21, 0xeb86d391); a = addUnsigned(a, olda); b = addUnsigned(b, oldb); c = addUnsigned(c, oldc); d = addUnsigned(d, oldd); } function toHex(n) { const hexChars = "0123456789abcdef"; let result = ""; for (let i = 0; i < 4; i++) { result += hexChars.charAt((n >> (i * 8 + 4)) & 0x0F) + hexChars.charAt((n >> (i * 8)) & 0x0F); } return result; } return toHex(a) + toHex(b) + toHex(c) + toHex(d); } // 自定义函数:获取远程图片并计算MD5 async function getRemoteImageMD5(imageUrl) { try { const response = await fetch(imageUrl, { method: 'GET', headers: { 'Accept': 'image/*' } }); if (!response.ok) throw new Error(`请求失败:${response.status}`); const arrayBuffer = await response.arrayBuffer(); return md5(arrayBuffer); } catch (error) { console.error('获取图片MD5失败:', error); return null; } } // 主逻辑:对比新旧MD5值 async function checkImageUpdate(imageUrl, oldMD5) { const newMD5 = await getRemoteImageMD5(imageUrl); if (!newMD5) return; if (newMD5 !== oldMD5) { alert('提示:目标图片内容已更新!'); // 可替换为自定义通知逻辑,比如在页面指定元素显示提示 // document.getElementById('update-notice').textContent = '图片已更新'; } else { console.log('图片未发生变化'); } } // 页面加载完成后自动执行校验 window.addEventListener('load', () => { // 替换为你的目标图片URL和Python生成的旧MD5值 const targetImageUrl = 'https://your-domain.com/target-image.jpg'; const storedOldMD5 = '填入Python生成的旧MD5字符串'; checkImageUpdate(targetImageUrl, storedOldMD5); });
关键注意事项
- 跨域问题:如果图片不在当前网站域名下,且对方服务器未配置
Access-Control-Allow-Origin头,浏览器会阻止请求。解决方式:要么让图片服务器开启跨域权限,要么用自己的服务器做代理转发图片请求。 - 自动执行时机:通过
window.addEventListener('load', ...)确保页面资源加载完成后自动触发校验,也可根据需求改为定时执行(比如用setInterval)。 - 旧值存储:建议从后端接口获取旧MD5值,或存在页面的
data-*属性中,避免硬编码。
内容的提问来源于stack exchange,提问作者chipmunktunic
相关产品推荐
相关产品推荐

