Security challenges
Capture-the-flag and reverse-engineering exercises often hide data with XOR. Repeat handles a repeating key, and XORing hidden data with a known part of the original reveals the key.
attack at dawn ⊕ key
XOR two or more inputs, from a single bit to many megabytes: binary, decimal, hex, Base64, ASCII or files. The calculation runs in the browser.
These inputs came from the link that opened this page, not from xor.pw.
Type or paste two inputs and the result appears here, or load an example.
The inputs lined up column by column. 0 zero padding k repeated input
Nothing to show yet.
Capture-the-flag and reverse-engineering exercises often hide data with XOR. Repeat handles a repeating key, and XORing hidden data with a known part of the original reveals the key.
attack at dawn ⊕ key
Diagnostic and configuration procedures for some vehicles and electronics ask for a code XORed with a fixed value. Results keep their leading zeros, so a four-digit code stays four digits.
1234 ⊕ 1f00 = 0d34
A key split into components, each held by a different person, is rebuilt by XORing all of them, one input per component.
8B3F… ⊕ 5E92… ⊕ C4D7…
XOR with 1 flips a bit and XOR with 0 leaves it alone, so the mask 11110000 inverts the high four bits.
11001010 ⊕ 11110000
Courses on binary logic, parity and ciphers. Numbers are XORed bit by bit, and the breakdown shows the bits lined up: 1100 ⊕ 1010 = 0110.
12 ⊕ 10 = 6
With a single input, the page converts between binary, decimal, hex, Base64 and ASCII.
48656c6c6f → Hello
XOR (exclusive or) compares two bits and gives 1 when they differ and 0 when they match. Longer inputs are lined up and XORed bit by bit.
| A | B | A ⊕ B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Anything XORed with itself is zero, and XORing twice with the same value undoes the first XOR: (a ⊕ k) ⊕ k = a. That is why XOR shows up in ciphers, checksums, parity and key splitting.
With three or more inputs the result is A ⊕ B ⊕ C …, and the order doesn’t matter. An empty input is left out, so a single input is simply shown in the output format: put hex in Input A, choose ASCII, and the page works as a converter.
: - _ , . and 0b prefixes are ignored.1,000,000, 1.000.000 and 10,00,000 are all a million. It’s stored in as few whole bytes as will hold it, so 32 lines up with one ASCII character.0x or \x prefixes are ignored.+ / or the URL-safe one with - _, with or without = padding. Spaces and line breaks are ignored.In binary, decimal, hex and Base64, characters typed in full width, such as 0xFF, and digits from other scripts, such as ٣ or ३, count as their ASCII forms, 0xFF and 3.
When the inputs aren’t the same length, choose how to line them up. Every shorter input is treated the same way. With 1011 and 11:
| Align right | Pads the shorter input with leading zeros, the way numbers line up. | 1011 ⊕ 0011 = 1000 |
|---|---|---|
| Align left | Pads it with trailing zeros, so the end of the longer input passes through. | 1011 ⊕ 1100 = 0111 |
| Repeat | Repeats the shorter input to full length, as in a repeating-key cipher. | 1011 ⊕ 1111 = 0100 |
| Truncate | Drops the part of the longer input that has no partner. | 10 ⊕ 11 = 01 |
Results keep their leading zeros, so they are as long as the longest input, or the shortest when truncating. ff00ff ⊕ ff0000 is 0000ff, not ff.
= padding. Like ASCII it needs whole bytes, so other lengths get leading zeros and a note.\x00, \n and \t, and a backslash appears as \\. Turn off escaping to read the bytes as UTF-8 text..xor added or removed, so XORing photo.jpg with a key gives photo.jpg.xor, and XORing that with the same key gives back photo.jpg.The calculation runs in the browser, in this page’s JavaScript. Typed inputs stay in the page: it doesn’t send them to the server or store them. A file is read by the browser from the device, and its contents stay in the page too. The page loads nothing from other sites: no trackers, ads or third-party fonts.
Ways to check how it works:
connect-src 'none', which tells the browser to block any connection the page tries to open. The developer tools show it in the page’s response headers, on the Network tab.The server delivers the page and its files. Like most web servers, it logs those requests: the time, the address each came from and how the browser describes itself.
The page keeps its display settings (formats, alignment, spacing and so on) in the browser’s local storage, under xor-calculator:settings, and stores nothing else. What this browser has stored for it now:
A share link carries its inputs in the link itself, after the #. Browsers leave that part out when they request a page; this page reads the inputs from it, fills them in and removes them from the address bar. Anyone with the link can read the inputs, and the link stays in the browser’s history.
Browser extensions can read and change the pages they’re allowed to, including this one, so what they do depends on the extensions installed.
xor.pw has been calculating XOR since 2013. Until 2026, every calculation went to the server, where PHP’s GMP library did the work. In 2026, Claude, an AI model made by Anthropic, designed and built this version, working with the site’s owner.
This version runs as JavaScript in the browser, and the server only delivers the page. Each input becomes bytes in a Uint8Array, the bytes are combined with JavaScript’s ^ operator, and decimal numbers are converted with BigInt.