Generator UnSafelink (Decode Base64 dari URL)
Masukkan URL safelink (contoh:
?url=aHR0cHM6Ly9leGFtcGxlLmNvbQ==) atau buka halaman ini dengan parameter ?url=....-- belum di-decode --
Fitur: mendeteksi parameter query (url,u,link,d), hash (#url=), dan pola path seperti
/s/<base64>. Mendukung base64 URL-safe ( '-' '_' ) dan padding otomatis.
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Generator UnSafelink — Decode Base64 URL</title>
<style>
body{font-family:system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial;margin:18px;background:#f7f7f8;color:#111}
.card{max-width:820px;margin:18px auto;padding:16px;border-radius:8px;background:#fff;box-shadow:0 6px 18px rgba(10,10,10,.06)}
h1{font-size:20px;margin:0 0 8px}
label{display:block;margin:10px 0 6px;font-size:13px;color:#333}
input[type=text]{width:100%;padding:10px 12px;border-radius:6px;border:1px solid #ddd;font-size:14px}
.row{display:flex;gap:8px;margin-top:10px}
button{padding:10px 12px;border-radius:6px;border:0;background:#0b76d1;color:#fff;font-weight:600;cursor:pointer}
button.secondary{background:#5a5a5a}
pre{background:#fafafa;border:1px dashed #e6e6e6;padding:12px;border-radius:6px;overflow:auto;white-space:pre-wrap;word-break:break-all}
.note{font-size:13px;color:#666;margin-top:10px}
</style>
</head>
<body>
<div class="card">
<h1>Generator UnSafelink (Decode Base64 dari URL)</h1>
<div class="note">Masukkan URL safelink (contoh: <code>?url=aHR0cHM6Ly9leGFtcGxlLmNvbQ==</code>) atau buka halaman ini dengan parameter <code>?url=...</code>.</div>
<label for="inp">Masukkan URL safelink atau tempel di sini</label>
<input id="inp" type="text" placeholder="https://dokumen-warnet.blogspot.com/p/generate.html?url=aHR0cDovL2Zlc3R5eS5jb20vcU0wYU9T" />
<div class="row">
<button id="btnDecode">Decode</button>
<button id="btnClear" class="secondary">Clear</button>
</div>
<label>Hasil (URL asli)</label>
<pre id="out">-- belum di-decode --</pre>
<div style="display:flex;gap:8px;margin-top:8px">
<button id="btnCopy" class="secondary">Copy hasil</button>
<button id="btnOpen">Buka di tab baru</button>
</div>
<div class="note" style="margin-top:12px">
Fitur: mendeteksi parameter query (url,u,link,d), hash (#url=), dan pola path seperti <code>/s/<base64></code>. Mendukung base64 URL-safe ( '-' '_' ) dan padding otomatis.
</div>
</div>
<script>
(function(){
// ---- util ----
function qs(name, url) {
try {
const u = new URL(url || window.location.href);
return u.searchParams.get(name);
} catch(e){ return null; }
}
function tryExtractFromPath(u) {
try {
const url = new URL(u);
// contoh path /s/<base64>
const m = url.pathname.match(/\/s\/([^\/?#]+)/i);
if (m) return m[1];
// coba last path segment jika kelihatan seperti base64
const segs = url.pathname.split('/').filter(Boolean);
const last = segs[segs.length-1] || '';
if (/^[A-Za-z0-9\-_]{8,}$/.test(last)) return last;
} catch(e){}
return null;
}
function tryExtractFromHash(u) {
try {
const url = new URL(u);
if (!url.hash) return null;
const h = url.hash.replace(/^#/, '');
const params = new URLSearchParams(h);
for (const k of ['url','u','link','d']) if (params.get(k)) return params.get(k);
// if whole hash looks like base64
if (/^[A-Za-z0-9\-_]+=*$/.test(h)) return h;
} catch(e){}
return null;
}
function normalizeBase64UrlSafe(str){
if (!str) return str;
let s = String(str).trim().replace(/\s+/g,'');
s = s.replace(/-/g, '+').replace(/_/g, '/');
const pad = s.length % 4;
if (pad === 2) s += '==';
else if (pad === 3) s += '=';
else if (pad === 1) {
// can't be valid base64, but try to salvage by removing last char
s = s.slice(0, -1);
}
return s;
}
function safeAtob(b64) {
try {
return atob(b64);
} catch(e){
try {
// some browsers need decodeURIComponent wrapper
return decodeURIComponent(escape(atob(b64)));
} catch(e2){
return null;
}
}
}
function decodeBase64ToStr(b64){
const norm = normalizeBase64UrlSafe(b64);
if (!norm) return null;
let res = safeAtob(norm);
if (!res) return null;
// sometimes value itself is percent-encoded
try {
const maybe = decodeURIComponent(res);
if (maybe && /https?:\/\//i.test(maybe)) res = maybe;
} catch(e){}
return res;
}
function findBase64Candidate(input){
// jika input sepertinya URL dengan parameter
try {
// langsung kalau input hanya base64
if (/^[A-Za-z0-9\-_]+=*$/.test(input) && input.length > 8) return input;
// jika input URL
const u = new URL(input);
// periksa query keys
for (const k of ['url','u','link','d']) {
const v = u.searchParams.get(k);
if (v) return v;
}
// check hash
const fromHash = tryExtractFromHash(input);
if (fromHash) return fromHash;
// check path
const fromPath = tryExtractFromPath(input);
if (fromPath) return fromPath;
// fallback: scan full URL for base64-like token
const all = input;
const match = all.match(/([A-Za-z0-9\-_]{8,}={0,2})/g);
if (match && match.length) {
// pilih token yang mengandung = atau paling panjang
match.sort((a,b)=> (b.length - a.length));
return match[0];
}
} catch(e){
// bukan URL — coba treat as plain base64-like
if (/^[A-Za-z0-9\-_]+=*$/.test(input) && input.length > 8) return input;
}
return null;
}
// ---- DOM ----
const inp = document.getElementById('inp');
const btnDecode = document.getElementById('btnDecode');
const out = document.getElementById('out');
const btnCopy = document.getElementById('btnCopy');
const btnOpen = document.getElementById('btnOpen');
const btnClear = document.getElementById('btnClear');
function show(text){
out.textContent = text || '';
}
function decodeFromInput(text){
if (!text || String(text).trim()==='') {
show('-- isi URL safelink dulu --');
return;
}
const candidate = findBase64Candidate(text);
if (!candidate) {
show('Gagal menemukan token base64 dalam input.');
return;
}
const decoded = decodeBase64ToStr(candidate);
if (!decoded) {
show('Gagal mendecode token base64. Mungkin bukan base64 yang valid.');
return;
}
show(decoded);
}
btnDecode.addEventListener('click', ()=> decodeFromInput(inp.value.trim()));
btnClear.addEventListener('click', ()=>{
inp.value = '';
show('-- belum di-decode --');
});
btnCopy.addEventListener('click', ()=>{
const txt = out.textContent || '';
if (!txt || txt.startsWith('--')) return alert('Tidak ada hasil untuk dicopy.');
navigator.clipboard.writeText(txt).then(()=> alert('Tersalin ke clipboard.'), ()=> alert('Gagal copy.'));
});
btnOpen.addEventListener('click', ()=>{
const url = out.textContent || '';
if (!url || url.startsWith('--')) return alert('Tidak ada URL untuk dibuka.');
try {
window.open(url, '_blank');
} catch(e){ alert('Gagal membuka URL.'); }
});
// jika halaman dibuka dengan ?url=... otomatis isi dan decode
(function autoFromQuery(){
try {
const p = new URL(window.location.href).searchParams;
for (const k of ['url','u','link','d']) {
const v = p.get(k);
if (v) {
inp.value = window.location.href; // simpan full URL supaya deteksi lebih baik
decodeFromInput(window.location.href);
return;
}
}
// jika tidak ada, tapi ada param base64 langsung di query (mis: ?aHR0c...)
const all = window.location.href;
const fallbackToken = (all.match(/([A-Za-z0-9\-_]{8,}={0,2})/g) || [])[0];
if (fallbackToken) {
inp.value = window.location.href;
decodeFromInput(window.location.href);
}
} catch(e){}
})();
})();
</script>
</body>
</html>

No comments:
Post a Comment