kone
소미소프트
소미소프트

코네 base64 오토 디코더

06/03/2026, 10:36:34
유틸
37275 views · 22 likes

클로드는 신이야!

1

딱 코네에서 base64 디코딩만하고 url만 하이퍼링크화 시켜주는 게 필요해서

클로드 한발 뽑아주니 원큐에 되더라

tampermonkey나 viloetmonkey에 추가해주면 됨

// ==UserScript==
// @name         Base64 Auto Decoder
// @namespace    http://tampermonkey.net/
// @version      1.1
// @author       you
// @match        *://*/*
// @run-at       document-idle
// @noframes
// @grant        none
// ==/UserScript==

(function () {
  'use strict';

  if (window.__b64DecoderLoaded) return;
  window.__b64DecoderLoaded = true;

  const DECODED_MARK = 'data-b64decoded';

  /* ============================== 설정 ============================== */
  const TARGET_SELECTORS = ['#post-article', '#post-comment', '.article-body', '.title'];
  const MAX_DECODE = 5;
  const MIN_B64_LEN = 7;

  const B64_CANDIDATE = new RegExp('[A-Za-z0-9+/]{' + MIN_B64_LEN + ',}={0,2}', 'g');
  const URL_REGEX = /((?:https?:\/\/|www\.)[^\s<>"'()]+)/gi;

  /* ============================== 유틸 ============================== */
  function looksLikeBase64(str) {
    return (
      str.length >= MIN_B64_LEN &&
      str.length % 4 !== 1 &&
      /^[A-Za-z0-9+/]+={0,2}$/.test(str)
    );
  }

  function isProbablyText(str) {
    if (!str) return false;
    let bad = 0;
    for (const ch of str) {
      const c = ch.codePointAt(0);
      if (c < 0x09 || (c > 0x0d && c < 0x20) || c === 0x7f) bad++;
    }
    return bad / str.length < 0.1;
  }

  function decodeOnce(str) {
    if (!looksLikeBase64(str)) return null;
    try {
      let s = str;
      const rem = s.length % 4;
      if (rem === 2) s += '==';
      else if (rem === 3) s += '=';
      const binary = atob(s);
      const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));
      return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
    } catch (e) {
      return null;
    }
  }

  function fullyDecode(str) {
    let current = str;
    let best = null;
    for (let i = 0; i < MAX_DECODE; i++) {
      const decoded = decodeOnce(current);
      if (decoded === null) break;
      if (!isProbablyText(decoded)) break;
      best = decoded;
      current = decoded;
    }
    return best;
  }

  /* ============================== DOM 조립 ============================== */
  function buildDecodedNodes(text) {
    const nodes = [];
    let last = 0;
    let m;
    URL_REGEX.lastIndex = 0;
    while ((m = URL_REGEX.exec(text)) !== null) {
      let url = m[0];
      const trailMatch = url.match(/[.,;:!?)\]}'"]+$/);
      let trail = '';
      if (trailMatch) {
        trail = trailMatch[0];
        url = url.slice(0, url.length - trail.length);
      }
      const start = m.index;
      if (start > last) nodes.push(document.createTextNode(text.slice(last, start)));

      const a = document.createElement('a');
      a.href = url.toLowerCase().startsWith('http') ? url : 'https://' + url;
      a.textContent = url;
      a.target = '_blank';
      a.rel = 'noopener noreferrer';
      nodes.push(a);

      if (trail) nodes.push(document.createTextNode(trail));
      last = start + m[0].length;
    }
    if (last < text.length) nodes.push(document.createTextNode(text.slice(last)));
    return nodes;
  }

  function processTextNode(node) {
    const text = node.nodeValue;
    if (!text) return;

    let match;
    let last = 0;
    let changed = false;
    const frag = document.createDocumentFragment();
    B64_CANDIDATE.lastIndex = 0;

    while ((match = B64_CANDIDATE.exec(text)) !== null) {
      const candidate = match[0];
      const decoded = fullyDecode(candidate);
      if (decoded === null) continue;

      changed = true;
      if (match.index > last) {
        frag.appendChild(document.createTextNode(text.slice(last, match.index)));
      }
      for (const n of buildDecodedNodes(decoded)) frag.appendChild(n);
      last = match.index + candidate.length;
    }

    if (!changed) return;
    if (last < text.length) frag.appendChild(document.createTextNode(text.slice(last)));

    const wrapper = document.createElement('span');
    wrapper.setAttribute(DECODED_MARK, '1');
    wrapper.appendChild(frag);
    node.parentNode.replaceChild(wrapper, node);
  }

  function processContainer(container) {
    const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, {
      acceptNode(node) {
        const p = node.parentNode;
        if (!p) return NodeFilter.FILTER_REJECT;
        const tag = p.nodeName;
        if (tag === 'SCRIPT' || tag === 'STYLE' || tag === 'A' || tag === 'TEXTAREA') {
          return NodeFilter.FILTER_REJECT;
        }
        if (node.parentElement && node.parentElement.closest('[' + DECODED_MARK + ']')) {
          return NodeFilter.FILTER_REJECT;
        }
        if (!node.nodeValue || !node.nodeValue.trim()) return NodeFilter.FILTER_REJECT;
        return NodeFilter.FILTER_ACCEPT;
      },
    });
    const targets = [];
    let n;
    while ((n = walker.nextNode())) targets.push(n);
    targets.forEach(processTextNode);
  }

  /* ====================== 실행 / 동적 콘텐츠 감시 ====================== */

  let observer = null;
  let scheduled = false;

  function runOnce() {
    TARGET_SELECTORS.forEach((sel) => {
      document.querySelectorAll(sel).forEach((el) => processContainer(el));
    });
  }

  function startObserve() {
    if (!observer) observer = new MutationObserver(() => scheduleRun());
    const root = document.body || document.documentElement;
    if (root) observer.observe(root, { childList: true, subtree: true, characterData: true });
  }

  function scheduleRun() {
    if (scheduled) return;
    scheduled = true;
    requestAnimationFrame(() => {
      scheduled = false;
      if (observer) observer.disconnect();
      runOnce();
      startObserve();
    });
  }

  runOnce();
  startObserve();
})();

22
7 comments
ㅁㅊ 너무 편하고
06/03
딱 원하는 기능하고 id나 클래스만 지정해주니 알잘딱해줌
ㄳㄳ 근데 가끔 복호화된 결과물이 두번 연속 나오는 경우가 있긴한데 왜 그런거임?
06/03
난 그런거 못봤는데
06/03
두번 되는 게시물 링크좀
로리 거유 소녀에게 최면을 걸어 섹스하는 애니메이션 영상 게임
영상
ロリ巨乳
08/30 7059 16
(직번)[몬무스]당신을 집착하는 니쿠사씨
동인
멕무
08/30 14212 17
[AI 번역][Kairaku Amnesia (Kinuo)] 가난한 아내가 집세를 보지로 갚을 때까지 ~28세 I컵 청초 아내, 악취나는 털복숭이 추남 집주인에게 NTR~
동인
crazyerdog
08/30 19705 29
[요청복구] RJ01295900 교배도시에 어서오세요 v1.03
복구
agnis
08/30 14076 21
펌,인도커리) 약혼자의 자매는 외모SSR, 성격은 최악지옥인 에로댄스여자2
동인
kjalar
08/30 23888 39
(청아) 꾸준 연필 37주차
창작
지나가던사람
08/30 6143 17
[기계번역] 마조 자위 입문 ~자, 딸딸이를 시작해보죠!~
영상
ejjsbs
08/30 22796 26
[구매보급,자체번역,료나] RJ01168443 버려진 아이
번역
쁠뿡
08/30 32108 38
[청아] アブジャン 신작 RJ01678278
영상
교미의요정
08/30 21502 20
제작 일기 ①「마차 안에서는」전투 시스템과 캐릭터 소개
정보
라임
08/30 7920 15
machi꺼 몇개
영상
Denia
08/30 27460 32
[구매보급]사랑받는 달콤한 LOVE✨ 키스✨ 처음으로 H의 리얼함✨ 작은 소꿉친구의 '좋아... ♡'×100... 벨로키스✦페로페로✦연속 질내 사정♡【처녀막 관통 SE】
소리
이름뭐하지
08/30 10995 26
(요청복구) 한글자막 아저씨 노치원 외 3개
영상
꽃사슴
08/30 30277 34
[구매보급][완전 신작! 호화 3편으로 구성♡]전편 귀 핥기 & 질내사정 아마아마 플레이♡ kakao 걸즈 컬렉션♡ 【스트로베리 피버♡】
소리
이름뭐하지
08/30 14332 30
[구매보급]다우너쿨계 성녀의 도스케베 참회
소리
이름뭐하지
08/30 14594 27
쌍둥이 JK 보지 메이드
소리
dasdaa
08/30 15103 36
[구매보급][자체번역]AI) 고고한 성녀 리제트, 패배하다 ~몸을 바치는 로그라이크 RPG~
번역
마카라이트
08/30 54336 49
【순애/노모】독신 헌터의 만남은 엘프의 숲에서♡
동인
HoneyWorks
08/30 47849 79
『마음과 몸~15일 만에 완전히 변한 용사의 아내~』NTR 게임 소개
정보
라임
08/30 9842 15
[요청복구] Treasure 내가 찾은 대체 할 수 없는 것
복구
뺏기는게좋은걸
08/30 31040 26
[직번] 강제 미소녀 검사 - 스파이로 의심받은 여자
동인
sgdvl
08/30 54454 71
[요청복구] 다우너 학생회 임원과 방과 후 남겨진 정액 수확 성지도~ "빨리 끝내고 싶은데…" 라고 말하면서 정액이 비어버릴 때까지 안 보내주는 개변태 농후 봉사~
소리
ilyug2
08/30 18151 32
[구매보급][번역요청] AI,TS 변전의 마녀 -나락 도시 그린자
미번
마카라이트
08/30 18503 27
요청복구 3종 (14일)
복구
쌀쌀쌀쌀
08/30 37354 34
[구매보급] ai) chui 작가 No.1 ~ No.30 모음
영상
푸니푸니
08/30 38909 34
후타, 후여, NT?R) [momomo] 꼬추가 크다고 이지메하는 건 좋지 않아요 엣... 크다아~
동인
라비쉬
08/30 52003 60
[직번/Dekosuke 18gou/팬스가] 네 남자 내가 좀 가져갈게
동인
BroadRight
08/30 61839 111
AI)블아)아비도스 전원임신 보테배sex
야짤
koreno1
08/30 14314 15
【순애】어른 놀이
동인
HoneyWorks
08/30 62143 96
호감도 짤 몇개
야짤
Denia
08/30 16847 29