Guest User

Untitled

a guest
Dec 25th, 2021
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         ПУК-СРЕНЬК
  3. // @version      2.1
  4. // @description  Encode and decode 2ch.hk fart code
  5. // @author       Anonymous
  6. // @include      *://2ch.*
  7. // @grant        none
  8. // @run-at       document-end
  9. // ==/UserScript==
  10.  
  11. const syms = [
  12.     "ПУК",
  13.     "СРЕНЬК",
  14.     "ХРЮК",
  15.     "УИИИ",
  16.     "ЛАХТА",
  17.     "ЛИБЕРАХА",
  18.     "ХОХЛЫ",
  19.     "СВИНОСОБАКА",
  20.     "ШВАЙНОКАРАСЬ",
  21.     "ЛОЛ",
  22.     "КЕК",
  23.     "АБУ",
  24.     "ДВАЧ",
  25.     "ПАРАША",
  26.     "ПОРИДЖ",
  27.     "ХРЮЧЕВО",
  28.     "СВИН",
  29.     "ПЕРДИКС",
  30.     "ПЫНЯ",
  31.     "ЧАЮ",
  32.     "ШУЕ",
  33.     "ЛЕВАК",
  34.     "ПРАВАК",
  35.     "КОМИГЛИСТ",
  36.     "ШВЯТЫЕ",
  37.     "ВАТА",
  38.     "ВОЛОДИН",
  39.     "ДОЛБИЛЬНЯ",
  40.     "ПЕРЕФОРС",
  41.     "КУНЧИК",
  42.     "АВАТАРКА",
  43.     "АНАЛЬЧИК",
  44. ];
  45.  
  46. const keysLen = Math.log2(syms.length);
  47.  
  48. const symsEncode = () => {
  49.     let result = {};
  50.  
  51.     syms.forEach((item, index) => {
  52.         result[
  53.             ("0".repeat(keysLen) + index.toString(2)).slice(-keysLen)
  54.         ] = item;
  55.     });
  56.  
  57.     return result;
  58. };
  59.  
  60. const symsDecode = () => {
  61.     let result = {};
  62.  
  63.     Object.entries(symsEncode()).forEach(([key, value]) => {
  64.         result[value] = key;
  65.     });
  66.  
  67.     return result;
  68. };
  69.  
  70. const rle = (string) => {
  71.     let arr = string.split("-"),
  72.         encoding = [],
  73.         previous = arr[0],
  74.         count = 1;
  75.  
  76.     for (let i = 1; i < arr.length; i++) {
  77.         if (arr[i] !== previous) {
  78.             encoding.push(count, previous);
  79.             count = 1;
  80.             previous = arr[i];
  81.         } else {
  82.             count++;
  83.         }
  84.     }
  85.  
  86.     encoding.push(count, previous);
  87.     return encoding.join("-").replace(/1-/g, "").replace(/(\d)-/g, "$1");
  88. };
  89.  
  90. const decode = (string) => {
  91.     const data = symsDecode();
  92.  
  93.     let ba = string
  94.         .split("-")
  95.         .map((item) => {
  96.             const count = /(\d*)(\w+)-?/.exec(item);
  97.  
  98.             if (count) {
  99.                 const key = item.replace(count[0], "");
  100.                 return data[key].repeat(parseInt(count[0]));
  101.             }
  102.  
  103.             return data[item];
  104.         })
  105.         .join("");
  106.  
  107.     if (ba.length > 15000 * 8) return string;
  108.  
  109.     const padLen = ba.length % 8;
  110.     ba = ba.substring(0, ba.length - padLen);
  111.  
  112.     return new TextDecoder().decode(
  113.         new Uint8Array(ba.match(/.{1,8}/g).map((c) => parseInt(c, 2)))
  114.     );
  115. };
  116.  
  117. const encode = (string) => {
  118.     let ba = new TextEncoder()
  119.         .encode(string)
  120.         .reduce((s, b) => s + b.toString(2).padStart(8, "0"), "");
  121.  
  122.     const padLen = keysLen - (ba.length % keysLen);
  123.     ba = ba + "0".repeat(padLen);
  124.  
  125.     const data = symsEncode();
  126.  
  127.     return rle(
  128.         ba
  129.             .match(new RegExp(`.{1,${keysLen}}`, "g"))
  130.             .map((item) => {
  131.                 return data[item];
  132.             })
  133.             .join("-")
  134.     );
  135. };
  136.  
  137. (() => {
  138.     const parse = (node) => {
  139.         const post = node.querySelector(".post__message");
  140.         if (post && post.textContent) {
  141.             const words = post.textContent
  142.                 .replace(/\t+/g, "")
  143.                 .split(/[\n,\s]+/);
  144.             const re = new RegExp(
  145.                 `(\\d+)?(${syms.join("|")})\-(\\S+)\-(\\d+)?(${syms.join("|")})`
  146.             );
  147.  
  148.             words.forEach((word) => {
  149.                 post.innerHTML = post.innerHTML.replace(re, (m) => {
  150.                     try {
  151.                         const thread = node.parentElement.parentElement.id.replace(
  152.                             /thread-/,
  153.                             ""
  154.                         );
  155.                         const board = window.location.pathname.split("/")[1];
  156.  
  157.                         return `<span style="color:green;font-size:1.21em">${decode(
  158.                             m
  159.                         )
  160.                             .replace(/<.*?>/g, "[Я у мамы идиот]")
  161.                             .replace(
  162.                                 /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim,
  163.                                 '<a href="$1" target="_blank" target="_blank" rel="nofollow noopener noreferrer">$1</a>'
  164.                             )
  165.                             .replace(
  166.                                 /(^|[^\/])(www\.[\S]+(\b|$))/gim,
  167.                                 '$1<a href="http://$2" target="_blank" rel="nofollow noopener noreferrer">$2</a>'
  168.                             )
  169.                             .replace(
  170.                                 /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim,
  171.                                 '<a href="mailto:$1" target="_blank" rel="nofollow noopener noreferrer">$1</a>'
  172.                             )
  173.                             .replace(
  174.                                 /\>>(\d{9})/gim,
  175.                                 '<a href="/' +
  176.                                     board +
  177.                                     "/res/" +
  178.                                     thread +
  179.                                     '.html#$1" class="post-reply-link" data-thread="' +
  180.                                     thread +
  181.                                     '" data-num="$1">&gt;&gt;$1</a>'
  182.                             )
  183.                             .replace(/\n/g, "<br>")}</span>`;
  184.                     } catch (err) {
  185.                         return m;
  186.                     }
  187.                 });
  188.             });
  189.         }
  190.     };
  191.  
  192.     document.querySelectorAll(".post").forEach((post) => parse(post));
  193.  
  194.     const observer = new MutationObserver((o) => {
  195.         o.forEach((i) => {
  196.             if (i.addedNodes) {
  197.                 i.addedNodes.forEach((n) => parse(n));
  198.             }
  199.         });
  200.     });
  201.     const config = { childList: true };
  202.     observer.observe(document.querySelector(".thread"), config);
  203.     observer.observe(document.querySelector("#posts-form"), config);
  204.  
  205.     let container = document.createElement("div");
  206.     container.className = "options__box";
  207.  
  208.     let enBtn = document.createElement("button");
  209.     enBtn.className = "desktop button";
  210.     enBtn.style = "color:green;font-weight:bold";
  211.     enBtn.textContent = `Зашифровать`;
  212.     enBtn.addEventListener("click", (e) => {
  213.         e.preventDefault();
  214.  
  215.         const comment = document.querySelector('[name="comment"]');
  216.         const selection = comment.value.substring(
  217.             comment.selectionStart,
  218.             comment.selectionEnd
  219.         );
  220.  
  221.         if (selection) {
  222.             const encoded = encode(selection);
  223.             const start = comment.selectionStart;
  224.             comment.value =
  225.                 comment.value.slice(0, start) +
  226.                 encoded +
  227.                 comment.value.slice(comment.selectionEnd);
  228.             comment.focus();
  229.             comment.setSelectionRange(start, start + encoded.length);
  230.         } else {
  231.             comment.value = encode(comment.value);
  232.         }
  233.     });
  234.     container.append(enBtn);
  235.  
  236.     let deBtn = document.createElement("button");
  237.     deBtn.className = "desktop button";
  238.     deBtn.style = "color:red;font-weight:bold";
  239.     deBtn.textContent = `Расшифровать`;
  240.     deBtn.addEventListener("click", (e) => {
  241.         e.preventDefault();
  242.  
  243.         try {
  244.             const comment = document.querySelector('[name="comment"]');
  245.             const selection = comment.value.substring(
  246.                 comment.selectionStart,
  247.                 comment.selectionEnd
  248.             );
  249.  
  250.             if (selection) {
  251.                 const decoded = decode(selection);
  252.                 const start = comment.selectionStart;
  253.                 comment.value =
  254.                     comment.value.slice(0, start) +
  255.                     decoded +
  256.                     comment.value.slice(comment.selectionEnd);
  257.                 comment.focus();
  258.                 comment.setSelectionRange(start, start + decoded.length);
  259.             } else {
  260.                 comment.value = decode(comment.value);
  261.             }
  262.         } catch (err) {}
  263.     });
  264.     container.append(deBtn);
  265.  
  266.     document.querySelector(".options").append(container);
  267. })();
Add Comment
Please, Sign In to add comment