Polybius square cipher
HELLO becomes 2315313134 on the Polybius square: each letter is replaced by the row and column of its cell in a five-by-five grid, with I and J sharing cell 24. Decrypt a digit string to get the letters back, no keyword needed. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- HELLO
- Calculation mode
- Encrypt
- Result
- 2315313134
- Length
- 10
- Letters mapped
- 5
- Pairs
- 5
The Polybius square is a classical substitution cipher that places the twenty-five Latin letters on a five-by-five grid and encodes each letter as the two digits of its row and column. In the textbook form used here, I and J share one cell so the full alphabet fits; encrypting HELLO yields the digit stream 2315313134, and decrypting that stream restores HELLO. You paste plain text or a digit string, choose encrypt or decrypt, and receive a deterministic result with pair counts and square metadata. Non-letters are skipped on encrypt so the ciphertext stays pure digit pairs; on decrypt, non-digit characters are ignored while digits are collected.
How the Polybius square maps letters to digit pairs
A classical Polybius square is a five-by-five table whose rows and columns are labeled one through five. The twenty-six Latin letters cannot fit one-to-one, so the standard classroom convention merges I and J into a single cell—here cell twenty-four—leaving twenty-five positions for A through Z. Reading left to right and top to bottom, A is eleven, B twelve, C thirteen, D fourteen, E fifteen, F twenty-one, and so on through Z at fifty-five.
Encryption walks the input once: each Latin letter, regardless of case, is replaced by its two-digit row-column code and appended to a continuous digit string; spaces, punctuation, digits already present in the plaintext, and other non-letters are skipped so the result is only valid pairs. Decryption reverses the process: every character that is a decimal digit is collected in order, then characters are consumed two at a time as row and column. Cell twenty-four always decrypts to I; J was never a separate cell on this square.
The path uses no network, no Date, and no randomness. This landing implements the classical five-by-five I/J-combined Polybius square only, not a six-by-six alphanumeric grid, not ADFGVX, and not automatic cryptanalysis of unknown squares.
Where Polybius square tools show up in real work
Introductory cryptography and discrete-math courses assign Polybius drills so students practice coordinate substitution before they meet polyalphabetic ciphers; a single trusted oracle that encrypts and decrypts with the textbook five-by-five grid speeds homework demos and auto-graders. Capture-the-flag warm-ups and puzzle hunts still hide digit-pair messages in plain sight, and solvers want a fast, predictable square rather than a general cryptanalysis suite. Support and content teams sometimes lightly encode spoilers, quiz answers, or internal labels as digit pairs and need the reverse path without installing a language-specific crypto library.
If you need a Caesar letter shift, Autokey or Beaufort keyword ciphers, Base32 encoding, or automatic frequency-analysis recovery of unknown keys, treat those as separate search intents and landings rather than overloading this classical Polybius square page.
What you can do with it
Classroom coordinate-substitution demos
Encrypt and decrypt sample words on the fixed 5×5 I/J square so intro-crypto lessons share one ground-truth digit mapping.
Puzzle and CTF digit-pair challenges
Encode or reverse Polybius digit streams on challenge strings without writing a one-off script for every problem set.
FAQ
What is a Polybius square cipher?
A classical cipher that places letters on a 5×5 grid and encodes each letter as its two-digit row and column. This tool uses the textbook square where I and J share one cell.
How do I decrypt a digit string?
Set mode to decrypt and paste the digits (spaces allowed). Digits are collected in order and read as pairs.
Why do I and J produce the same code?
The classical 5×5 square has only twenty-five cells for twenty-six letters, so I and J share cell 24. Decrypting 24 always returns I.
Are spaces and punctuation encrypted?
No. On encrypt, non-letters are skipped. On decrypt, non-digit characters are ignored while digits form the pairs.
What does it cost?
The browser tool is free and runs locally.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/enc/polybius \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"HELLO"}'const res = await fetch("https://api.kit.forhosting.com/enc/polybius", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "HELLO"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/polybius",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "HELLO"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/polybius", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"HELLO"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"HELLO"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/polybius", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "HELLO"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.polybius",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Decryption rejects an odd number of digits immediately with a clear invalid_input error, because incomplete row-column pairs cannot map back to letters.
How the Polybius square maps letters to digit pairs
If the collected digit count is odd, the request fails with invalid_input naming the odd-digit rule, because a lone trailing digit cannot address a cell. If a pair uses a digit outside one through five, or otherwise does not appear on the classical square, the request also fails rather than inventing a letter. There is no secret keyword, no modular alphabet shift, and no random padding—only a fixed open table—so identical text and mode always produce identical JSON.
What you send and what you get back
Send a required string field named text and an optional mode field set to encrypt or decrypt. Encrypt mode maps letters to continuous digit pairs; decrypt mode maps digit pairs back to uppercase letters. Classic checks include encrypting HELLO to 2315313134, decrypting that stream back to HELLO, mapping J to the same code as I, and confirming that a five-digit ciphertext is rejected rather than silently truncating. When mode is omitted, encrypt is the default so a minimal payload still does useful work. On success the response echoes mode and the original text, returns result as the transformed string, length of that result, letters_mapped and pairs as how many cells were encoded or decoded, digit_count as the length of the digit stream involved, plus square, ij_combined, alphabet, and cipher labels for clients that assert the profile they hit. Missing text, non-string objects for text, unsupported mode values, strings longer than the documented maximum, decrypt payloads with no digits, an odd number of digits, and digit pairs outside the classical one-to-five grid all fail with invalid_input and a clear English message. Validation failures do not consume prepaid balance. Pricing for successful API calls is the published base of $0.002 per item.
Where Polybius square tools show up in real work
Because this capability is a pure parse engine, API pricing is the published base of $0.002 per successful item and failed validation does not consume balance.
Integration use cases
Lightweight label and spoiler encoding
Turn quiz answers or internal labels into row-column digit pairs and decode them later with the same contract in browser or API.