(function () { 'use strict'; // ── Tiny MD5 (pure JS, no external deps) ──────────────────────────── // Based on the public-domain MD5 algorithm by MD5 Specification (RFC 1321) function md5(str) { function safeAdd(x, y) { var lsw=(x&0xffff)+(y&0xffff); return (((x>>16)+(y>>16)+(lsw>>16))<<16)|(lsw&0xffff); } function bitRotateLeft(num, cnt) { return (num<>>(32-cnt)); } function md5cmn(q,a,b,x,s,t){ return safeAdd(bitRotateLeft(safeAdd(safeAdd(a,q),safeAdd(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); } var bs = []; for (var i=0;i>5]|=(str.charCodeAt(i/8)&0xff)<<(i%32); } var len=str.length*8; bs[len>>5]|=0x80<<(len%32); bs[(((len+64)>>>9)<<4)+14]=len; var a=1732584193,b=-271733879,c=-1732584194,d=271733878; for(var blk=0;blk>>(bi*8))&0xff); hex+=(byte_<16?'0':'')+byte_.toString(16); } } return hex; } // ── SHA via Web Crypto API ─────────────────────────────────────────── function shaHash(algorithm, text) { var encoder = new TextEncoder(); var data = encoder.encode(text); var algo = algorithm === 'SHA-1' ? 'SHA-1' : algorithm; // SHA-256, SHA-512 return crypto.subtle.digest(algo, data).then(function(buf) { var arr = Array.from(new Uint8Array(buf)); return arr.map(function(b){ return (b<16?'0':'')+b.toString(16); }).join(''); }); } // ── Bootstrap ──────────────────────────────────────────────────────── function typoCssVarsForEl(typo, prefix, el) { if (!typo || typeof typo !== 'object') return; var map = { family:'font-family', weight:'font-weight', style:'font-style', decoration:'text-decoration', transform:'text-transform', sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m', lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m', letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m', wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m' }; Object.keys(map).forEach(function(k) { if (typo[k] !== undefined && typo[k] !== '') { var v = typo[k]; if (['sizeDesktop','sizeTablet','sizeMobile'].indexOf(k) !== -1) v = v + (typo.sizeUnit || 'px'); else if (['lineHeightDesktop','lineHeightTablet','lineHeightMobile'].indexOf(k) !== -1) v = v + (typo.lineHeightUnit || ''); else if (['letterSpacingDesktop','letterSpacingTablet','letterSpacingMobile'].indexOf(k) !== -1) v = v + (typo.letterSpacingUnit || 'px'); else if (['wordSpacingDesktop','wordSpacingTablet','wordSpacingMobile'].indexOf(k) !== -1) v = v + (typo.wordSpacingUnit || 'px'); el.style.setProperty(prefix + map[k], String(v)); } }); } document.querySelectorAll('.bkbg-hg-app').forEach(function(root) { var opts; try { opts = JSON.parse(root.getAttribute('data-opts') || '{}'); } catch(e) { return; } var o = { title: opts.title || 'Hash Generator', subtitle: opts.subtitle || '', defaultAlgorithm: opts.defaultAlgorithm || 'SHA-256', defaultInput: opts.defaultInput || '', showMD5: opts.showMD5 !== false, showSHA1: opts.showSHA1 !== false, showSHA256: opts.showSHA256 !== false, showSHA512: opts.showSHA512 === true, showCompare: opts.showCompare !== false, autoHash: opts.autoHash !== false, accentColor: opts.accentColor || '#6366f1', sectionBg: opts.sectionBg || '#f5f3ff', cardBg: opts.cardBg || '#ffffff', inputBg: opts.inputBg || '#f9fafb', hashBg: opts.hashBg || '#1e1b4b', hashColor: opts.hashColor || '#a5b4fc', titleColor: opts.titleColor || '#111827', subtitleColor: opts.subtitleColor || '#6b7280', labelColor: opts.labelColor || '#374151', titleFontSize: parseInt(opts.titleFontSize) || 26, contentMaxWidth: parseInt(opts.contentMaxWidth) || 700 }; var enabledAlgos = []; if (o.showMD5) enabledAlgos.push('MD5'); if (o.showSHA1) enabledAlgos.push('SHA-1'); if (o.showSHA256) enabledAlgos.push('SHA-256'); if (o.showSHA512) enabledAlgos.push('SHA-512'); if (!enabledAlgos.length) return; var activeAlgo = enabledAlgos.indexOf(o.defaultAlgorithm) >= 0 ? o.defaultAlgorithm : enabledAlgos[0]; // ── Render skeleton ──────────────────────────────────────────── var wrap = root; typoCssVarsForEl(opts.typoTitle, '--bkbg-hg-tt-', wrap); typoCssVarsForEl(opts.typoSubtitle, '--bkbg-hg-st-', wrap); root.innerHTML = '
' + (o.title ? '

' + o.title + '

' : '') + (o.subtitle ? '

' + o.subtitle + '

' : '') + '
' + '' + '' + '
' + '
' + enabledAlgos.map(function(a) { return ''; }).join('') + '
' + '
' + renderRowsHtml('', [], o) + '
' + (o.showCompare ? '
' + '
Verify / Compare Hash
' + '
' + '' + '' + '
' + '
' : '') + '
'; var textareaEl = root.querySelector('#hg-input'); var algosEl = root.querySelector('#hg-algos'); var rowsEl = root.querySelector('#hg-rows'); var compareInEl = root.querySelector('#hg-compare-in'); var compareBadge= root.querySelector('#hg-compare-badge'); // computed hash cache var hashCache = {}; function renderRowsHtml(text, computed, opt) { if (!text) { return enabledAlgos.map(function(a) { return '
' + '' + a + '' + '— enter text to generate —' + '
'; }).join(''); } return enabledAlgos.map(function(a) { var val = computed[a] || '…'; return '
' + '' + a + '' + '' + val + '' + '' + 'Copied!' + '
'; }).join(''); } // ── Compute hashes ───────────────────────────────────────────── var hashTimer = null; function computeHashes(text) { if (!text) { hashCache = {}; rowsEl.innerHTML = renderRowsHtml('', {}, o); if (compareBadge) compareBadge.style.display = 'none'; return; } rowsEl.innerHTML = renderRowsHtml(text, {}, o); bindCopyBtns(); // MD5 — synchronous if (o.showMD5) { var m = md5(text); hashCache['MD5'] = m; var el = root.querySelector('#hg-val-MD5'); if (el) el.textContent = m; } // SHA — async (Web Crypto) function doSha(algo) { if (!window.crypto || !window.crypto.subtle) { var el2 = root.querySelector('#hg-val-' + algo.replace(/[^a-z0-9]/gi,'-')); if (el2) el2.textContent = '(Web Crypto not available)'; return; } shaHash(algo, text).then(function(hex) { hashCache[algo] = hex; var rowEl = root.querySelector('#hg-val-' + algo.replace(/[^a-z0-9]/gi,'-')); if (rowEl) rowEl.textContent = hex; updateCompare(); }).catch(function() {}); } if (o.showSHA1) doSha('SHA-1'); if (o.showSHA256) doSha('SHA-256'); if (o.showSHA512) doSha('SHA-512'); updateCompare(); bindCopyBtns(); } function updateCompare() { if (!compareInEl || !compareBadge) return; var expected = compareInEl.value.trim().toLowerCase(); if (!expected || !hashCache[activeAlgo]) { compareBadge.style.display = 'none'; return; } var actual = hashCache[activeAlgo].toLowerCase(); var match = (actual === expected); compareBadge.className = 'bkbg-hg-compare-badge ' + (match ? 'match' : 'nomatch'); compareBadge.textContent = match ? '✓ Match' : '✗ No match'; compareBadge.style.display = 'inline-block'; } function bindCopyBtns() { root.querySelectorAll('.bkbg-hg-row-copy').forEach(function(btn) { btn.addEventListener('click', function() { var algo = btn.getAttribute('data-algo'); var hash = hashCache[algo]; var toast = root.querySelector('#hg-toast-' + algo.replace(/[^a-z0-9]/gi,'-')); if (!hash) return; navigator.clipboard.writeText(hash).then(function() { if (toast) { toast.classList.add('show'); setTimeout(function(){ toast.classList.remove('show'); }, 1800); } }).catch(function(){}); }); }); } // ── Input debounce ───────────────────────────────────────────── textareaEl.addEventListener('input', function() { if (!o.autoHash) return; clearTimeout(hashTimer); hashTimer = setTimeout(function(){ computeHashes(textareaEl.value); }, 300); }); // ── Algo tab switching ───────────────────────────────────────── algosEl.querySelectorAll('.bkbg-hg-algo-btn').forEach(function(btn) { btn.addEventListener('click', function() { activeAlgo = btn.getAttribute('data-algo'); algosEl.querySelectorAll('.bkbg-hg-algo-btn').forEach(function(b) { var act = b.getAttribute('data-algo') === activeAlgo; b.classList.toggle('active', act); b.style.background = act ? o.accentColor : ''; b.style.borderColor = act ? o.accentColor : ''; b.style.color = act ? '#fff' : o.labelColor; }); updateCompare(); }); }); // ── Compare input ────────────────────────────────────────────── if (compareInEl) { compareInEl.addEventListener('input', updateCompare); } // ── Initial hash (if prefilled) ──────────────────────────────── if (o.defaultInput) { computeHashes(o.defaultInput); } // ── Manual hash button (if autoHash off) ────────────────────── if (!o.autoHash) { var btn = document.createElement('button'); btn.textContent = 'Generate Hashes'; btn.style.cssText = 'margin-top:10px;padding:10px 22px;border-radius:9px;border:none;background:' + o.accentColor + ';color:#fff;font-size:14px;font-weight:700;cursor:pointer;transition:opacity 0.2s;'; textareaEl.parentNode.insertBefore(btn, textareaEl.nextSibling); btn.addEventListener('click', function(){ computeHashes(textareaEl.value); }); } }); })();