Decode base64-encoded links in some pastebins and make URLs clickable
Size
9.1 KB
Version
2.5
Created
Nov 5, 2025
Updated
about 1 month ago
1// ==UserScript==
2// @name FMHY Base64 Auto Decoder
3// @version 2.5
4// @author Rust1667
5// @description Decode base64-encoded links in some pastebins and make URLs clickable
6// @match *://rentry.co/*
7// @match *://rentry.org/*
8// @match *://pastes.fmhy.net/*
9// @match *://bin.disroot.org/?*#*
10// @match *://privatebin.net/?*#*
11// @match *://textbin.xyz/?*#*
12// @match *://bin.idrix.fr/?*#*
13// @match *://privatebin.rinuploads.org/?*#*
14// @match *://pastebin.com/*
15// @grant none
16// @icon https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://fmhy.net&size=64
17// @namespace https://greasyfork.org/users/980489
18// @downloadURL https://update.greasyfork.org/scripts/485772/FMHY%20Base64%20Auto%20Decoder.user.js
19// @updateURL https://update.greasyfork.org/scripts/485772/FMHY%20Base64%20Auto%20Decoder.meta.js
20// ==/UserScript==
21
22
23(function() {
24 'use strict';
25
26 // Regular expression to match base64-encoded strings
27 const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/;
28
29 // Function to decode base64 string
30 function decodeBase64(encodedString) {
31 return atob(encodedString);
32 }
33
34 // Function to check if a string is a URL
35 function isURL(str) {
36 const pattern = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i;
37 return pattern.test(str);
38 }
39
40 // Different script for different pastebins
41 var currentUrl = window.location.href;
42 const rentryOrSnowbinRegex = /^(https?:\/\/(?:rentry\.co|rentry\.org|pastes\.fmhy\.net)\/[\w\W]+)/;
43 const FMHYmainBase64PageRegex = /^https:\/\/rentry\.(?:co|org)\/fmhybase64(?:#.*)?/i;
44 const fmhyBase64RawRentryPageRegex = /^https:\/\/rentry\.(co|org)\/FMHYBase64\/raw$/i;
45 const privatebinDomainsRegex = /^(https?:\/\/(?:bin\.disroot\.org|privatebin\.net|textbin\.xyz|bin\.idrix\.fr|privatebin\.rinuploads\.org)\/[\w\W]+)/;
46 const pastebinComRegex = /^https:\/\/pastebin\.com\/.*/;
47
48 // PASTEBIN.COM
49 if (pastebinComRegex.test(currentUrl)) {
50 let elements = document.querySelectorAll('.de1');
51 elements.forEach(function(element) {
52 let text = element.textContent.trim();
53 if (text.startsWith('aHR0')) {
54 let decodedText = decodeBase64(text);
55
56 // Get the color of the original text
57 let originalColor = window.getComputedStyle(element).color;
58
59 // Turn each valid URL in the decoded text into a clickable link
60 let htmlWithLinks = decodedText.replace(
61 /(https?:\/\/[^\s]+)/g, // find anything that looks like a URL
62 '<a href="$1" target="_blank" style="color: ' + originalColor + ';">$1</a>'
63 );
64
65 // Replace newlines with <br> for readability
66 htmlWithLinks = htmlWithLinks.replace(/\n/g, '<br>');
67
68 // Replace the original text with the new clickable version
69 element.innerHTML = htmlWithLinks;
70 }
71 });
72
73
74 //RENTRY OR PASTES.FMHY
75 } else if (rentryOrSnowbinRegex.test(currentUrl) && !fmhyBase64RawRentryPageRegex.test(currentUrl)) {
76
77 // Select appropriate tags based on the URL matching
78 var elementsToCheck = FMHYmainBase64PageRegex.test(currentUrl) ? document.querySelectorAll('code') : document.querySelectorAll('code, p');
79
80 // Loop through each selected element
81 elementsToCheck.forEach(function(element) {
82 // Get the content of the element
83 var content = element.textContent.trim();
84
85 // Check if the content matches the base64 regex
86 if (base64Regex.test(content)) {
87 // Decode the base64-encoded string
88 var decodedString = decodeBase64(content).trim();
89
90 // If the decoded string has URLs, decode it and linkify when possible
91 if (isURL(decodedString) || (decodedString.includes('http') && decodedString.includes('\n'))) {
92
93 // One line
94 if (!decodedString.includes('\n')) {
95 var link = document.createElement('a');
96 link.href = decodedString;
97 link.textContent = decodedString;
98 link.target = '_self'; // Open link in the same tab
99 element.textContent = ''; // Clear the content of the element
100 element.appendChild(link); // Append the link to the element
101 }
102 //Multiple lines
103 else {
104 const lines = decodedString.split("\n");
105 const links = lines.map(line => isURL(line.trim()) ? "<a href='" + line.trim() + "'>" + line.trim() + "</a>" : line.trim());
106 element.innerHTML = links.join("<br>");
107 }
108
109 }
110 }
111 });
112
113
114
115 //FMHY-BASE64 RAW RENTRY PAGE
116 } else if (fmhyBase64RawRentryPageRegex.test(currentUrl)) {
117
118 // Find all lines starting with "* `"
119 const lines = document.body.innerText.split('\n');
120 for (let i = 0; i < lines.length; i++) {
121 const line = lines[i];
122 if (line.includes('`')) {
123 const startIndex = line.indexOf('`');
124 const endIndex = line.lastIndexOf('`');
125 const encodedText = line.substring(startIndex + 1, endIndex).trim();
126 const decodedText = atob(encodedText);
127 const newLine = line.substring(0, startIndex) + decodedText + line.substring(endIndex + 1);
128 lines[i] = newLine;
129 }
130 }
131
132 // Update the page content with decoded lines
133 document.body.innerText = lines.join('\n');
134
135
136
137
138 // PRIVATEBIN
139 } else if (privatebinDomainsRegex.test(currentUrl)) {
140
141 // Wait for the decryption process to finish
142 function waitForDecryption() {
143 const prettyPrintElement = document.getElementById('prettyprint');
144 if (prettyPrintElement && prettyPrintElement.textContent.trim() !== '') {
145 let decryptedText = prettyPrintElement.innerHTML.trim();
146 const lines = decryptedText.split('\n');
147
148 // Flag to track if any modifications were made
149 let modified = false;
150
151 // Iterate through each line
152 lines.forEach(line => {
153 // Check if the line contains a potential Base64 encoded string
154 if (base64Regex.test(line)) {
155 // Attempt to decode the potential Base64 encoded string
156 try {
157 const decodedText = decodeBase64(line);
158 // Trim the decoded text before checking if it's a URL
159 const trimmedText = decodedText.trim();
160 // If trimmed decoded string is a URL, make it clickable
161 if (isURL(trimmedText)) {
162 // Replace the line with the decoded and linked text
163 decryptedText = decryptedText.replace(line, '<a href="' + trimmedText + '">' + trimmedText + '</a>');
164 modified = true;
165 }
166 } catch (error) {
167 // If an error occurs during decoding, show it in an alert message
168 //alert("Unable to decode the string: " + line);
169 }
170 } else if (line.startsWith('`') && line.endsWith('`')) {
171 // Check if the line starts and ends with backticks
172 let textInsideBackticks = line.slice(1, -1);
173 // Check if textInsideBackticks is a Base64 encoded string
174 if (base64Regex.test(textInsideBackticks)) {
175 // Attempt to decode the text inside backticks
176 try {
177 const decodedText = decodeBase64(textInsideBackticks);
178 // Trim the decoded text before checking if it's a URL
179 const trimmedText = decodedText.trim();
180 // If trimmed decoded string is a URL, make it clickable
181 if (isURL(trimmedText)) {
182 // Replace the line with the decoded and linked text
183 decryptedText = decryptedText.replace(line, '<a href="' + trimmedText + '">' + trimmedText + '</a>');
184 modified = true;
185 }
186 } catch (error) {
187 // If an error occurs during decoding, show it in an alert message
188 //alert("Unable to decode the string: " + textInsideBackticks);
189 }
190 }
191 }
192 });
193
194 // If modifications were made, show modified text in the page
195 if (modified) {
196 prettyPrintElement.innerHTML = decryptedText;
197 }
198
199 } else {
200 setTimeout(waitForDecryption, 500); // Check again in 500ms
201 }
202 }
203
204 // Start waiting for decryption
205 waitForDecryption();
206 }
207
208
209
210
211
212})();
213