Skip to content

Instantly share code, notes, and snippets.

@Jaid
Created January 17, 2026 13:22
Show Gist options
  • Select an option

  • Save Jaid/45b18b105ab0546a51caf0dc9f535fb8 to your computer and use it in GitHub Desktop.

Select an option

Save Jaid/45b18b105ab0546a51caf0dc9f535fb8 to your computer and use it in GitHub Desktop.
Simple text compression
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Text Encoder</title>
<style>
body {
margin: 0;
padding: 0;
font-family: monospace;
}
.header {
display: flex;
align-items: center;
padding: 10px;
border-bottom: 1px solid #ccc;
background-color: #f8f8f8;
}
.header select, .header span, .header button {
margin-right: 10px;
}
.container {
display: flex;
flex-direction: column;
height: calc(100vh - 41px); /* Adjust for header height */
}
.input-area, .output-area {
flex: 1;
padding: 10px;
box-sizing: border-box;
}
.input-area {
border-bottom: 1px solid #ccc;
}
textarea {
width: 100%;
height: 100%;
border: none;
resize: none;
font-family: monospace;
font-size: 14px;
}
pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
font-size: 14px;
}
</style>
</head>
<body>
<div class="header">
<select id="cipher">
<option value="none" selected>None</option>
<option value="rot13">Rot13</option>
</select>
<select id="compression">
<option value="none">None</option>
<option value="deflate" selected>Deflate</option>
</select>
<select id="encoding">
<option value="base64" selected>Base64</option>
<option value="base64url">Base64Url</option>
<option value="base62">Base62</option>
<option value="base85">Base85</option>
<option value="hex">Hex</option>
</select>
<span id="charcount">0 characters</span>
<button id="copy">Copy</button>
</div>
<div class="container">
<div class="input-area">
<textarea id="input" placeholder="Enter text here..."></textarea>
</div>
<div class="output-area">
<pre id="output"></pre>
</div>
</div>
<script>
function rot13(str) {
return str.replace(/[a-zA-Z]/g, function(char) {
const code = char.charCodeAt(0);
const base = code < 97 ? 65 : 97;
return String.fromCharCode((code - base + 13) % 26 + base);
});
}
function toBase62(bytes) {
let num = BigInt(0);
for (const byte of bytes) {
num = num * 256n + BigInt(byte);
}
const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (num === 0n) return '0';
let result = '';
while (num > 0n) {
result = chars[Number(num % 62n)] + result;
num /= 62n;
}
return result;
}
function toBase85(bytes) {
const chars = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstu";
let result = '';
let i = 0;
const len = bytes.length;
while (i < len) {
let tuple = 0;
let count = 0;
for (let j = 0; j < 4; j++) {
if (i < len) {
tuple = (tuple * 256) + bytes[i];
i++;
count++;
} else {
tuple *= 256;
}
}
let encoded = '';
for (let j = 4; j >= 0; j--) {
if (j < count + 1 || count === 4) {
encoded = chars[tuple % 85] + encoded;
tuple = Math.floor(tuple / 85);
}
}
result += encoded;
}
return result;
}
function toHex(bytes) {
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
}
async function getProcessedBytes(text, compression) {
const encoder = new TextEncoder();
const bytes = encoder.encode(text);
const readable = new ReadableStream({
start(controller) {
controller.enqueue(bytes);
controller.close();
}
});
let processedStream = readable;
if (compression === 'deflate') {
const compressor = new CompressionStream('deflate');
processedStream = readable.pipeThrough(compressor);
}
const reader = processedStream.getReader();
const chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
}
let totalLength = 0;
for (const chunk of chunks) {
totalLength += chunk.length;
}
const processed = new Uint8Array(totalLength);
let offset = 0;
for (const chunk of chunks) {
processed.set(chunk, offset);
offset += chunk.length;
}
return processed;
}
async function updateOutput() {
let text = document.getElementById('input').value;
const cipher = document.getElementById('cipher').value;
const compression = document.getElementById('compression').value;
const encoding = document.getElementById('encoding').value;
if (cipher === 'rot13') {
text = rot13(text);
}
const bytes = await getProcessedBytes(text, compression);
let encoded;
if (encoding === 'base64') {
encoded = btoa(String.fromCharCode(...bytes));
} else if (encoding === 'base64url') {
encoded = btoa(String.fromCharCode(...bytes))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
} else if (encoding === 'base62') {
encoded = toBase62(bytes);
} else if (encoding === 'base85') {
encoded = toBase85(bytes);
} else if (encoding === 'hex') {
encoded = toHex(bytes);
}
document.getElementById('output').textContent = encoded;
document.getElementById('charcount').textContent = `${encoded.length} characters`;
}
document.getElementById('input').addEventListener('input', updateOutput);
document.getElementById('cipher').addEventListener('change', updateOutput);
document.getElementById('compression').addEventListener('change', updateOutput);
document.getElementById('encoding').addEventListener('change', updateOutput);
document.getElementById('copy').addEventListener('click', () => {
const output = document.getElementById('output').textContent;
navigator.clipboard.writeText(output).then(() => {
alert('Copied to clipboard!');
}).catch(err => {
console.error('Failed to copy: ', err);
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment