Security challenges
Capture-the-flag and reverse-engineering exercises often hide data with XOR. Repeat handles a key shorter than the message, 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, so it keeps working offline.
These inputs came from the link that opened this page, not from xor.pw.
Type or paste an input and the result appears here, or load an example.
The inputs lined up column by column. 0 zero padding k repeated input
Once there’s a result, this lines up the inputs and the result column by column.
Capture-the-flag and reverse-engineering exercises often hide data with XOR. Repeat handles a key shorter than the message, 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 unchanged, 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 …. XOR is commutative and associative, so neither the order nor the grouping of the inputs changes the result.
An empty input is left out, which gives the same result as an input of zeros, so a single input is shown as it is, in the result’s format. Select Hex for Input A and ASCII for the result, and the calculator 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 takes one byte, like 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 110:
| Align right | Pads the shorter input with leading zeros, the way numbers line up. | 1011 ⊕ 0110 = 1101 |
|---|---|---|
| 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. When the lengths don’t divide evenly, the last repetition is cut short. | 1011 ⊕ 1101 = 0110 |
| Truncate | Drops the part of the longer input that has no partner. | 101 ⊕ 110 = 011 |
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 \\. Spaces show as spaces, so a result can start or end with spaces that are hard to see; the breakdown marks each one with ␣. 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.
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.