Decode Hex strings on Voz

Decode Hex, Base64

  1. // ==UserScript==
  2. // @name Decode Hex strings on Voz
  3. // @namespace Decode Hex strings on Voz
  4. // @version 4.1
  5. // @icon https://www.google.com/s2/favicons?sz=64&domain=voz.vn
  6. // @author kylyte
  7. // @description Decode Hex, Base64
  8. // @match https://voz.vn/t/*
  9. // @run-at document-idle
  10. // @license GPL-3.0
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. function decodeHex(hexString) {
  17. hexString = hexString.replace(/\s+/g, '');
  18. if (!/^[0-9A-Fa-f]{2,}$/.test(hexString)) return hexString;
  19. let hexStr = '';
  20. try {
  21. for (let i = 0; i < hexString.length; i += 2) {
  22. hexStr += String.fromCharCode(parseInt(hexString.substr(i, 2), 16));
  23. }
  24. if (/^[\x20-\x7E]*$/.test(hexStr) && hexStr.length > 3) {
  25. return hexStr;
  26. } else {
  27. return hexString;
  28. }
  29. } catch {
  30. return hexString;
  31. }
  32. }
  33.  
  34. function decodeBase64(base64String) {
  35. if (!/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(base64String)) return base64String;
  36. try {
  37. let binaryString = atob(base64String);
  38. if (/^[\x20-\x7E]*$/.test(binaryString) && binaryString.length > 3) {
  39. return binaryString;
  40. } else {
  41. return base64String;
  42. }
  43. } catch {
  44. return base64String;
  45. }
  46. }
  47.  
  48. function decodeContent(elements, regex, decodeFunc) {
  49. elements.forEach(element => {
  50. const excludedSelectors = [
  51. '.fr-box.bbWrapper.fr-ltr.fr-basic.fr-top',
  52. '.tooltip.tooltip--basic',
  53. '.bbImage',
  54. '.bbMediaJustifier',
  55. '.link'
  56. ];
  57. if (excludedSelectors.some(selector => element.closest(selector))) return;
  58. let walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false);
  59. let textNode;
  60. while (textNode = walker.nextNode()) {
  61. let content = textNode.nodeValue;
  62. let matches = content.match(regex);
  63. if (matches) {
  64. matches.forEach(match => {
  65. content = content.replace(new RegExp(escapeRegExp(match), 'g'), decodeFunc(match));
  66. });
  67. textNode.nodeValue = content;
  68. }
  69. }
  70. });
  71. }
  72.  
  73. function escapeRegExp(string) {
  74. return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  75. }
  76.  
  77. function main() {
  78. let elements = document.querySelectorAll('.bbWrapper');
  79. decodeContent(elements, /\b([0-9A-Fa-f]{2}\s*){4,}\b/g, decodeHex);
  80. decodeContent(elements, /(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})/g, decodeBase64);
  81. }
  82.  
  83. main();
  84. })();