W3docs

String Functions

ROT-13 Transformer

Apply the classic ROT-13 cipher. Letters shift by 13 positions; other characters are left alone.

About ROT-13

ROT13 ("rotate by 13") is a substitution cipher that shifts every letter 13 places through the alphabet, wrapping Z back to A. Because the Latin alphabet has 26 letters and 13 is exactly half of that, applying ROT13 a second time undoes the first — the same operation both encodes and decodes. This tool takes whatever text you paste, shifts each A–Z and a–z character by 13 positions, and leaves everything else — digits, punctuation, spaces, accented letters, emoji — exactly as it was.

Under the hood the transform is a single regex replace: input.replace(/[A-Za-z]/g, (ch) => { ... }) matches each letter, reads its code with charCodeAt, picks a base of 65 for uppercase or 97 for lowercase, then computes ((code - base + 13) % 26) + base and converts back with String.fromCharCode. The % 26 wraps the shift at the end of the alphabet instead of spilling into unrelated Unicode ranges. This matches PHP's built-in str_rot13() byte-for-byte, so output is interchangeable between the two. Everything runs in your browser — no request is sent, so pasted text never leaves your machine.

ROT13 is not encryption: it provides no real confidentiality, since knowing the algorithm — or simply running the text through again — instantly reverses it. Its actual use is obscuring text that shouldn't be immediately visible on the page: spoilers, puzzle solutions, and joke punchlines on forums and wikis, a convention going back to Usenet. It's also handy for generating a reversible test string that isn't plain text, or for decoding ROT13'd content someone else posted. If you need to actually protect data rather than just obscure it, reach for a real cipher such as AES instead.

Examples

Encode, then decode by resubmittingtext
Input:   Hello, ROT13 world!
Output:  Uryyb, EBG13 jbeyq!

Input:   Uryyb, EBG13 jbeyq!
Output:  Hello, ROT13 world!

This is the tool's own placeholder pair. Paste the output back into the source box and Submit again to get the original text back — shifting by 13 twice is a full 26-letter loop back to the start.

The transform as a standalone JS functionjs
function rot13(input) {
  return input.replace(/[A-Za-z]/g, (ch) => {
    const code = ch.charCodeAt(0);
    const base = code >= 97 ? 97 : 65;
    return String.fromCharCode(((code - base + 13) % 26) + base);
  });
}

rot13("Attack at dawn"); // "Nggnpx ng qnja"

This is what the tool runs client-side. Only A-Za-z characters match the regex and get shifted; digits, spaces, and punctuation fall through untouched.

Same result from PHP's str_rot13()php
echo str_rot13("Attack at dawn");
// Nggnpx ng qnja

PHP ships ROT13 as a built-in with identical A-Z/a-z-only behavior, so output matches this tool exactly — useful when checking a PHP backend against it.

Frequently asked questions

Is ROT13 a form of encryption?

No. ROT13 is obfuscation, not encryption — it uses no key, and anyone who knows it's ROT13 (or just runs the text through again) reads it instantly. Use it to hide text from a casual glance, not from anyone who actually wants to read it.

Why does ROT13 use a shift of 13, specifically?

13 is exactly half of the 26-letter alphabet, so shifting twice (13 + 13 = 26) lands back on the original letter. That makes ROT13 its own inverse — a shift of any other size would need a different amount to undo it.

Does ROT13 affect numbers, spaces, or punctuation?

No. Only the letters A-Z and a-z are shifted; digits, punctuation, whitespace, and non-Latin characters pass through unchanged. abc123! becomes nop123! — the 123! stays exactly as typed.

How do I decode a ROT13 string?

Run it through ROT13 again — encoding and decoding are the same operation. Paste the ciphertext into this tool and click Submit to get the plaintext back.

Is ROT13 the same thing as Base64?

No. Base64 re-encodes bytes into a 64-character alphabet, changing both the character set and the string's length. ROT13 only rotates letters in place, so the output stays the same length and case pattern as the input.