// ==UserScript== // @name Arca base64 autodecoder // @version 1.14 // @author Laria // @match https://arca.live/b/*/* // @description 아카라이브 Base64 자동 복호화 // @icon https://www.google.com/s2/favicons?sz=64&domain=arca.live // @run-at document-end // @namespace https://greasyfork.org/users/1235854 // @downloadURL none // ==/UserScript== /* * 1.0 - Release * 1.1 - Invalid character update (replace -> replaceAll) * 1.11 - Improved show multiple links * 1.12 - Show Single links Bugfixlinks * 1.13 - Show Single links Bugfix * 1.14 - base64 add padding func */ const regArr = [ /(aHR0cDovL|aHR0cHM6Ly)(\w|=|\+|\/)*(?=[^\+=\w\/])/g, /(YUhSMGNEb3ZM|YUhSMGNITTZMe)(\w|=|\+|\/)*(?=[^\+=\w\/])/g, /(WVVoU01HTkViM1pN|WVVoU01HTklUVFpNZ)(\w|=|\+|\/)*(?=[^\+=\w\/])/g, ] const regInvalid = /[^\w\+\/=]/; function base64AddPadding(str) { return str + Array((4 - str.length % 4) % 4 + 1).join('='); } var Base64 = { _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", decode : function (input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (i < input.length) { enc1 = this._keyStr.indexOf(input.charAt(i++)); enc2 = this._keyStr.indexOf(input.charAt(i++)); enc3 = this._keyStr.indexOf(input.charAt(i++)); enc4 = this._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = Base64._utf8_decode(output); return output; }, // private method for UTF-8 decoding _utf8_decode : function (utftext) { var string = ""; var i = 0; var c = 0; var c1 = 0; var c2 = 0; var c3 = 0; while ( i < utftext.length ) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } } var hindex = 0; //total index const max_iter = 3; //max try decode iteration attamp, def:3 var lastSelected = document; var lastSelectedTime = Date.now(); function createLink(orig, index, url, depth) { return '' + index.toString() + '번째 링크 (base64 깊이: ' + depth.toString() + ')' + '
[ ' + orig.toString() + ' ]'; } function replacerGen(numIter) { return function(match) { try { return_f = ""; //return msg console.log(match) var converted = Base64.decode(base64AddPadding(match)); for(var i=0; i 1) { return_f+='[ ' + match.toString() + ' ]'; nindex = 1; converted.forEach(function(k) { if (k != '') { return_f+='
' + createLink('링크 자동 분할 : ' + nindex.toString() + '번째', hindex, k, numIter+1); hindex++; nindex++; } }); hindex--; //last components nindex--; return_f = '분할된 링크 총 ' + nindex + '개 ' + return_f; } else return_f+=createLink(match, hindex, converted, numIter+1); return return_f } catch(e) { console.log(e); console.log('base64 변환 실패 : ' + match); } return '[base64 변환 실패 : ' + match + ']'; } } //function disabled function selClicked(event) { var sel = document.getSelection().toString(); if (!sel.match(regInvalid) && sel.length >= 10 && lastSelectedTime + 200 < Date.now()) { try { var converted = Base64.decode(sel); } catch (e) { return; } finally { this.innerHTML = this.innerHTML.replace(sel, converted); this.removeEventListener('click', selClicked); } } } (function() { 'use strict'; var article = document.getElementsByClassName("article-content")[0]; for(var i=0; i