mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-06-06 06:53:56 +02:00
8ff45957c8
Made-with: Cursor
93 lines
3.1 KiB
JavaScript
93 lines
3.1 KiB
JavaScript
// z85 encoding (ZeroMQ Base85)
|
|
import BaseTransformer from '../BaseTransformer.js';
|
|
|
|
export default new BaseTransformer({
|
|
name: 'Z85',
|
|
priority: 250,
|
|
category: 'encoding',
|
|
// Z85 uses a different character set than standard Base85
|
|
charset: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#',
|
|
func: function(text) {
|
|
const bytes = new TextEncoder().encode(text);
|
|
let result = '';
|
|
const originalLength = bytes.length;
|
|
|
|
// Z85 encodes 4 bytes into 5 characters
|
|
for (let i = 0; i < bytes.length; i += 4) {
|
|
const chunk = Array.from(bytes.slice(i, i + 4));
|
|
const chunkLength = chunk.length;
|
|
while (chunk.length < 4) chunk.push(0);
|
|
|
|
// Convert 4 bytes to 32-bit integer
|
|
let value = 0;
|
|
for (let j = 0; j < 4; j++) {
|
|
value = (value << 8) + chunk[j];
|
|
}
|
|
|
|
// Convert to base 85 (5 digits)
|
|
const z85Chars = [];
|
|
for (let j = 0; j < 5; j++) {
|
|
z85Chars.unshift(this.charset[value % 85]);
|
|
value = Math.floor(value / 85);
|
|
}
|
|
|
|
result += z85Chars.join('');
|
|
}
|
|
|
|
// Store original length for decoding
|
|
this._z85OriginalLength = originalLength;
|
|
|
|
return result;
|
|
},
|
|
reverse: function(text) {
|
|
const bytes = [];
|
|
|
|
// Z85 decodes 5 characters into 4 bytes
|
|
for (let i = 0; i < text.length; i += 5) {
|
|
const chunk = text.substring(i, i + 5);
|
|
if (chunk.length < 5) break;
|
|
|
|
// Convert 5 base-85 digits to 32-bit integer
|
|
let value = 0;
|
|
for (const char of chunk) {
|
|
const idx = this.charset.indexOf(char);
|
|
if (idx === -1) return ''; // Invalid character
|
|
value = value * 85 + idx;
|
|
}
|
|
|
|
// Extract 4 bytes
|
|
bytes.push((value >> 24) & 0xFF);
|
|
bytes.push((value >> 16) & 0xFF);
|
|
bytes.push((value >> 8) & 0xFF);
|
|
bytes.push(value & 0xFF);
|
|
}
|
|
|
|
// Trim to original length if we stored it
|
|
if (this._z85OriginalLength !== undefined) {
|
|
bytes.length = Math.min(bytes.length, this._z85OriginalLength);
|
|
} else {
|
|
// Remove trailing null bytes (padding)
|
|
while (bytes.length > 0 && bytes[bytes.length - 1] === 0) {
|
|
bytes.pop();
|
|
}
|
|
}
|
|
|
|
try {
|
|
return new TextDecoder().decode(new Uint8Array(bytes));
|
|
} catch (e) {
|
|
return '';
|
|
}
|
|
},
|
|
preview: function(text) {
|
|
if (!text) return '[z85]';
|
|
const result = this.func(text.slice(0, 4));
|
|
return result.substring(0, 10) + '...';
|
|
},
|
|
detector: function(text) {
|
|
// Z85 uses specific character set
|
|
const z85Pattern = /^[0-9a-zA-Z.\-:+=^!\/\*\?&<>()\[\]{}@%$#]+$/;
|
|
return text.length >= 5 && z85Pattern.test(text) && text.length % 5 === 0;
|
|
}
|
|
});
|
|
|