Convert to binary

Attempts to convert any numbers on all webpages to base 2. Based on the video https://youtu.be/rDDaEVcwIJM

当前为 2024-09-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Convert to binary
  3. // @author Nick M
  4. // @namespace https://youtu.be/rDDaEVcwIJM
  5. // @version 2024-09-29
  6. // @description Attempts to convert any numbers on all webpages to base 2. Based on the video https://youtu.be/rDDaEVcwIJM
  7. // @match *://*/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. const baseChars = ["ı","l"];
  16. const multipliers = {
  17. 'k': {value: 1000, replacement:[""]},
  18. 'm': 1000000,
  19. 'b': 1000000000
  20. };
  21.  
  22. function toNewBase(str) {
  23. // Remove commas and handle multipliers
  24. str = str.replace(/,/g, '');
  25. let multiplier = 1;
  26. let match = str.match(/([0-9.]+)([kMB])?/i);
  27. if (match) {
  28. str = match[1];
  29. if (match[2]) multiplier = multipliers[match[2].toLowerCase()];
  30. }
  31.  
  32. // Convert to number and apply multiplier
  33. let n = parseFloat(str) * multiplier;
  34.  
  35. // Handle decimal part
  36. let intPart = Math.floor(n);
  37. let fracPart = n - intPart;
  38.  
  39. let newStr = "";
  40.  
  41. // Convert integer part
  42. if (intPart === 0) return baseChars[0];
  43. while (intPart > 0) {
  44. let remainder = intPart % baseChars.length;
  45. newStr = baseChars[remainder] + newStr;
  46. intPart = Math.floor(intPart / baseChars.length);
  47. }
  48.  
  49. // Add decimal part if exists
  50. if (fracPart > 0) {
  51. newStr += '.';
  52. for (let i = 0; i < 4; i++) { // Convert up to 4 decimal places
  53. fracPart *= baseChars.length;
  54. let digit = Math.floor(fracPart);
  55. newStr += baseChars[digit];
  56. fracPart -= digit;
  57. if (fracPart === 0) break;
  58. }
  59. }
  60.  
  61. return newStr;
  62. }
  63.  
  64. function replaceNumbers(node) {
  65. if (node.nodeType === Node.TEXT_NODE) {
  66. node.textContent = node.textContent.replace(/\b\d{1,3}(,\d{3})*(\.\d+)?([kMB])?\b|\b\d+(\.\d+)?([kMB])?\b/gi, match => toNewBase(match));
  67. } else if (node.nodeType === Node.ELEMENT_NODE && !['SCRIPT', 'STYLE', 'NOSCRIPT'].includes(node.nodeName)) {
  68. for (let i = 0; i < node.childNodes.length; i++) {
  69. replaceNumbers(node.childNodes[i]);
  70. }
  71. }
  72. }
  73.  
  74. let mutatedNodes = new Set();
  75. let processingScheduled = false;
  76.  
  77. function scheduleProcessing() {
  78. if (!processingScheduled) {
  79. processingScheduled = true;
  80. setTimeout(() => {
  81. processMutations();
  82. processingScheduled = false;
  83. }, 10);
  84. }
  85. }
  86.  
  87. function processMutations() {
  88. mutatedNodes.forEach(node => {
  89. if (node.isConnected) {
  90. replaceNumbers(node);
  91. }
  92. });
  93. mutatedNodes.clear();
  94. }
  95.  
  96. function observeChanges() {
  97. const observer = new MutationObserver(mutations => {
  98. mutations.forEach(mutation => {
  99. if (mutation.type === 'childList') {
  100. mutation.addedNodes.forEach(node => {
  101. if (node.nodeType === Node.ELEMENT_NODE) {
  102. mutatedNodes.add(node);
  103. }
  104. });
  105. } else if (mutation.type === 'characterData') {
  106. mutatedNodes.add(mutation.target);
  107. }
  108. });
  109. scheduleProcessing();
  110. });
  111.  
  112. observer.observe(document.body, {
  113. childList: true,
  114. subtree: true,
  115. characterData: true
  116. });
  117.  
  118. }
  119.  
  120. // Initial replacement
  121. replaceNumbers(document.body);
  122.  
  123. // Observe future changes
  124. observeChanges();
  125. })();