Skip to content

Latest commit

 

History

History
152 lines (127 loc) · 4.86 KB

File metadata and controls

152 lines (127 loc) · 4.86 KB

Transformers

Transformers are instantiated using BaseTransformer class. Category is automatically assigned from the directory name.

Directory Structure

Categories (auto-assigned from directory name):

  • encoding/ - Base64, Hex, Binary, URL, HTML, etc.
  • cipher/ - ROT13, Caesar, Vigenère, Atbash, etc.
  • unicode/ - Cursive, Medieval, Monospace, Bubble, etc.
  • case/ - Snake case, Kebab case, Title case, etc.
  • technical/ - Morse, Braille, NATO, Brainfuck, etc.
  • fantasy/ - Elder Futhark, Tengwar, Klingon, Aurebesh, etc.
  • ancient/ - Hieroglyphics, Ogham, Roman Numerals, etc.
  • format/ - Leetspeak, Pig Latin, Reverse, etc.
  • visual/ - Emoji speak, Rovarspraket, etc.
  • special/ - Randomizer, etc.

Creating a Transformer

Required Properties

  • name - Display name (string)
  • func - Encoding function (text) => string
  • priority - Decoder priority (number, 1-310)

Optional Properties

  • reverse - Decoding function (text) => string (auto-generated if map provided)
  • map - Character mapping object (auto-generates reverse)
  • detector - Detection function (text) => boolean (for universal decoder)
  • preview - Preview function (text) => string (defaults to func)
  • canDecode - Boolean (default: true)
  • description - Help text (string)

Example: Character Map (Auto-generates reverse)

import BaseTransformer from '../BaseTransformer.js';

export default new BaseTransformer({
    name: 'Cursive',
    priority: 85,
    map: {
        'a': '𝒶', 'b': '𝒷', 'c': '𝒸',
        // ... more mappings
    },
    func: function(text) {
        return [...text].map(c => this.map[c] || c).join('');
    }
    // reverse is auto-generated from map!
});

Example: Custom Transformer

import BaseTransformer from '../BaseTransformer.js';

export default new BaseTransformer({
    name: 'Base64',
    priority: 270,
    detector: function(text) {
        const cleaned = text.trim().replace(/\s/g, '');
        return cleaned.length >= 4 && /^[A-Za-z0-9+\/=]+$/.test(cleaned);
    },
    func: function(text) {
        // Encoding logic
        const encoder = new TextEncoder();
        const bytes = encoder.encode(text);
        let binaryString = '';
        for (let i = 0; i < bytes.length; i++) {
            binaryString += String.fromCharCode(bytes[i]);
        }
        return btoa(binaryString);
    },
    reverse: function(text) {
        // Decoding logic
        const binaryString = atob(text);
        const bytes = new Uint8Array(binaryString.length);
        for (let i = 0; i < binaryString.length; i++) {
            bytes[i] = binaryString.charCodeAt(i);
        }
        const decoder = new TextDecoder('utf-8');
        return decoder.decode(bytes);
    },
    preview: function(text) {
        if (!text) return '[base64]';
        const full = this.func(text);
        return full.substring(0, 12) + (full.length > 12 ? '...' : '');
    }
});

Example: Encoding-Only (No Reverse)

export default new BaseTransformer({
    name: 'Random Mix',
    priority: 0,
    canDecode: false,
    func: function(text) {
        // Encoding logic only
        return randomized;
    }
});

Priority Guide

Higher priority = more specific pattern (used for decoder result ordering):

  • 310: Most exclusive (Semaphore Flags)
  • 300: Exclusive character sets (Binary, Morse, Braille, Brainfuck, Tap Code)
  • 290: Hexadecimal
  • 285: Pattern-based (Pig Latin, Dovahzul)
  • 280: Base32
  • 270-275: Base encodings (Base64, Base58, Base45)
  • 260: A1Z26
  • 150: Active transform (user context)
  • 100: High confidence (Fantasy scripts, unique Unicode ranges)
  • 85: Unicode transformations (default)
  • 70: Common encodings (URL, HTML, ASCII85)
  • 60: Ciphers (ROT13, Caesar)
  • 50: Generic text transforms
  • 20: Low confidence generic
  • 1: Invisible text (last resort)
  • 0: Cannot decode / encode-only

After Adding

  1. Place file in appropriate category directory
  2. Run npm run build:transforms
  3. Test in webapp
  4. Add detector function if format has distinctive patterns
  5. Optionally add test cases to tests/test_universal.js
  6. Add a one-line description for the transform’s name in DESCRIPTIONS inside build/readme-transform-section.js, then run node build/readme-transform-section.js and merge the printed block into the Text Transformations section of the root README.md (the script exits with an error if a transform is missing from DESCRIPTIONS)

Testing

All transformers with reverse are automatically tested by tests/test_universal.js.

For transformers with known limitations (e.g., lowercases input), add to limitations object in test_universal.js:

const limitations = {
    'your_transform': {
        issues: 'Description of changes',
        normalize: { lowercase: true, stripEmoji: true }
    }
};