Scytale cipher
With 5 columns, HELLOWORLD becomes HWEOLRLLOD: the text is written row by row into a grid, like a strip wound round a rod, and read down each column. The same column count reverses it, and every character is kept. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- HELLOWORLD
- Columns
- 5
- Calculation mode
- Encrypt
- Text
- HWEOLRLLOD
- Length
- 10
The scytale cipher is a classical transposition cipher from ancient Greece: you wrap a strip of writing around a rod of fixed diameter, write along the rod, then unwind the strip so the letters scramble into a column-wise order. This capability implements that idea as a deterministic column transposition: you supply the text, an integer columns key (the diameter), and mode encrypt or decrypt. Encryption writes the characters into a grid row by row and reads them down each column; decryption reverses the same map with the same key so length and every character—including spaces and punctuation—are preserved.
How the scytale transposition works
A scytale is not a substitution cipher: every letter stays itself; only order changes. Think of the key as the number of columns on a cylinder. For encrypt mode the engine lays your string into a rectangular layout filled left to right, top to bottom, with as many columns as you chose.
Incomplete last rows leave empty cells that are never filled and never emitted, so ciphertext length always equals plaintext length and no pad character is invented. Reading down column zero, then column one, and so on produces the ciphertext—the same scramble you would see if you unwound a strip written around a rod of that diameter. Decrypt mode rebuilds that column-first layout from the ciphertext and reads left to right again, restoring the original string whenever the same columns value is used.
Choosing a wrong columns key on decrypt yields a wrong permutation, not a crash—exactly the behavior students expect when they try nearby diameters.
Classroom, CTF, and product use — and cost
History and cryptography courses use the scytale to introduce transposition before substitution and modern ciphers; labs can show that knowing the diameter recovers the message while wrong diameters do not. Capture-the-flag authors hide short flags under a columns key and verify solutions against this same deterministic routine. Documentation writers embed encrypt and decrypt pairs in tutorials without maintaining a separate offline script.
Do not treat scytale as confidentiality for real secrets—it is a teaching and puzzle tool—but do treat the columns key as the secret parameter of the toy system.
What you can do with it
Cryptography classroom labs
Demonstrate classical transposition: students encrypt a sentence with a columns key, then recover it by decrypting with the same diameter.
CTF and puzzle authors
Hide short challenge strings under a scytale key and verify solver submissions against the same deterministic encrypt/decrypt pair.
Docs and playground demos
Generate stable ciphertext examples for tutorials and classical-cipher playgrounds without hand-maintaining permutation tables.
FAQ
What is a scytale cipher?
A classical transposition cipher: characters keep their values but change position according to a column (diameter) key. This tool implements the standard row-write, column-read model.
Why must columns be at least 2?
A diameter of one column leaves the text in the same order, so it is not a meaningful scytale key.
Does decryption need the same columns value?
Yes. Encrypt and decrypt use the same integer key. A different columns value applies a different permutation and will not restore the original text.
Are spaces and punctuation preserved?
Yes. Every character in the string participates in the transposition. Nothing is stripped, lowercased, or padded.
What does it cost?
The interactive page runs free in your browser.
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/scytale \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"HELLOWORLD","columns":5,"mode":"encrypt"}'const res = await fetch("https://api.kit.forhosting.com/enc/scytale", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "HELLOWORLD",
"columns": 5,
"mode": "encrypt"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/scytale",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "HELLOWORLD",
"columns": 5,
"mode": "encrypt"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/scytale", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"HELLOWORLD","columns":5,"mode":"encrypt"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"HELLOWORLD","columns":5,"mode":"encrypt"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/scytale", 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": "HELLOWORLD",
"columns": 5,
"mode": "encrypt"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.scytale",
"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
Fewer than two columns is rejected with invalid_input, because a single column leaves the message unchanged and is not a meaningful scytale diameter. Use the tool free on this page, or call the identical pure algorithm by API at $0.002 per request for classroom demos, CTF helpers, and documentation examples that must stay reproducible.
How the scytale transposition works
Columns of one or zero would either copy the text unchanged or be undefined as a diameter; this API therefore requires an integer of at least two and reports invalid_input when that rule is broken.
Calling the API and reading the result
Spaces, newlines, and punctuation travel through the grid like any other character; nothing is stripped or lowercased, which keeps passwords-style demos and multi-line classroom strings intact. Round-trip by encrypting with a given columns value and decrypting with the same value; different keys will not restore the original. Empty text is allowed and returns an empty result with length zero. Send three fields: text (the plaintext or ciphertext string), columns (integer diameter, minimum two), and mode (encrypt or decrypt; short aliases such as enc and dec are accepted). Missing text, a non-string text, a missing or non-integer columns value, columns less than two, or an unknown mode all fail with invalid_input and a message that names the problem so forms and scripts can surface fixable feedback. On success the JSON includes text (the transformed string), mode (canonical encrypt or decrypt), columns (the integer key you used), and length (character count of the result, equal to the input length). Prefer this endpoint when search intent is specifically scytale or classical rod transposition; modern AEAD tools serve a different intent and a different threat model.
Classroom, CTF, and product use — and cost
Product teams that ship classical-cipher playgrounds can call the API for server-side checks while visitors experiment free in the browser. Because the work is pure parse-time string indexing with no external service, latency stays low and the cost model is simple: try unlimited conversions free on this page, then automate identical inputs at $0.002 per successful item from prepaid KIT balance when you integrate from scripts or backend services. That parity keeps homework solutions, CI goldens, and production demos aligned. Map UI labels to encrypt and decrypt, validate columns client-side with the same minimum of two, and surface invalid_input messages next to the diameter control when users submit one column or a non-integer.