XOR cipher decoder and key recovery
XOR text or hex against a key, brute-force single-byte XOR by English scoring, and recover repeating-key XOR by Hamming-distance keysize detection.
Open in ctfpalXOR is the workhorse of CTF crypto because it is symmetric, byte-oriented, and trivial to implement badly. Every XOR challenge is one of three shapes: a single-byte key, a short repeating key, or a key as long as the message that got reused.
Single-byte XOR: 256 candidates
Try all 256 bytes and score each result for English-likeness. This is the same chi-squared machinery the Caesar solver uses, extended to bytes rather than letters, with a bonus for printable characters and for flag-shaped substrings. It is exhaustive and instant.
Repeating-key XOR: find the keysize first
For a repeating key, the trick is the normalised Hamming distance. Take two adjacent blocks of length K, count the differing bits, divide by K. When K is the true keysize, both blocks were XORed with the same key bytes, so the distance reflects only the plaintext difference and drops sharply. Test K from 2 to 40, take the lowest few, then split the ciphertext into K columns - each column is single-byte XOR, solved by the previous step.
def normalised_distance(data, k):
blocks = [data[i * k:(i + 1) * k] for i in range(4)]
pairs = [(a, b) for i, a in enumerate(blocks) for b in blocks[i + 1:]]
total = sum(hamming(a, b) for a, b in pairs) / len(pairs)
return total / k # normalise so keysizes are comparable
best = sorted(range(2, 41), key=lambda k: normalised_distance(ct, k))[:3]Worked example
Single-byte XOR
Input
322b212d011604393a72301d73311d30713471303173202e713fResult
picoCTF{x0r_1s_r3v3rs1bl3} (key 0x42), ranked first out of all 256 key bytes by English scoreHex input, single-byte key. The brute force is exhaustive - no guessing required.
Load this example in the workspacePart of a module
4. XOR and the cost of reusing a key
Break single-byte and repeating-key XOR, then recover both plaintexts from a reused one-time pad by crib dragging.
Practise on real challenges
Go deeper
- XOR, crib dragging, and the two-time padSingle-byte XOR, repeating-key XOR, and keystream reuse are three faces of the same weakness. How to recover a key length from Hamming distance, drag a crib across a XOR of two plaintexts, and know when a stream cipher has handed you the answer.
Related tools
XOR crib dragging for many-time pads
Recover both plaintexts when a one-time pad key is reused, by dragging a guessed word along the XOR of two ciphertexts.
Vigenere cipher solver with automatic key recovery
Decrypt Vigenere with a known key, or recover the key from ciphertext alone using index-of-coincidence period detection and per-column chi-squared.
Hex to text converter
Convert hexadecimal to text and back, tolerating whitespace, commas, and `0x` prefixes. Runs entirely in your browser.
Cipher identifier and automatic decoder
Paste anything and find out what it is. ctfpal runs every decoder and rotation, including multi-pass cascades, and ranks results by English-likeness and flag patterns.