ROT5 digit cipher
0123456789 becomes 5678901234: each digit moves five places on a circle of ten, while letters, spaces and dashes stay where they are. Apply it a second time and the original digits return. Useful for masking phone or order numbers in demos. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- 0123456789
- Result
- 5678901234
- Input
- 0123456789
- Text
- 5678901234
- Digits rotated
- 10
A ROT5 digit cipher is the numeric cousin of the classic ROT13 letter rotation: every ASCII digit from zero through nine is shifted five places on a ten-digit circle, so zero becomes five, one becomes six, two becomes seven, three becomes eight, four becomes nine, and the second half of the alphabet of digits maps back the other way. Because five is half of ten, applying the same substitution a second time restores the original string—encode and decode are identical operations. Letters, punctuation, spaces, and any non-digit Unicode code points pass through unchanged, which makes ROT5 ideal for light obfuscation of phone numbers, order IDs, PINs embedded in mixed text, or CTF-style puzzle strings without touching the surrounding prose. Enter any non-empty text; the tool returns the transformed string, how many digits were rotated, how many non-digit characters were left alone, and a short status message.
What ROT5 does to digits and what it leaves alone
ROT5 belongs to the family of modular substitution ciphers used in classic crypto puzzles and lightweight text toys. The alphabet is the ten ASCII digits zero through nine. For any digit character d whose numeric value is n in zero through nine, the cipher emits the single character for (n plus five) modulo ten.
That table is fixed and public: zero maps to five, one to six, two to seven, three to eight, four to nine, five to zero, six to one, seven to two, eight to three, and nine to four. Because the shift equals half the alphabet size, the mapping is an involution—each symbol is its own inverse—so there is no separate decode mode and no secret key.
Anything that is not an ASCII digit is copied verbatim: uppercase and lowercase letters, spaces, hyphens in phone numbers, currency symbols, newlines, and multi-byte Unicode all survive. Full-width digit forms and other numeral systems outside the ASCII range are not rewritten; only the ten characters with code points forty-eight through fifty-seven participate. When you re-submit the result as input, you recover the original text for every digit that was present, which is the standard round-trip check teachers and CTF authors use to verify a ROT5 implementation.
What you can do with it
CTF and classroom cipher drills
Students apply ROT5 to digit runs in challenge prompts, then apply it again to verify the involution property before moving on to harder classical ciphers.
Light obfuscation of IDs in demos
Product demos and screenshots replace order numbers or sample phone digits with ROT5 while keeping separators and labels readable for the audience.
FAQ
What is ROT5?
ROT5 rotates each ASCII digit 0–9 by five positions modulo 10. Zero becomes five, one becomes six, and so on; five maps back to zero. Non-digits are left unchanged.
How do I decode ROT5?
Apply ROT5 again. The mapping is an involution: running the same transform twice restores the original digits.
Does ROT5 change letters?
No. Only ASCII digits 0–9 are rewritten. Letters, spaces, punctuation, and other Unicode characters pass through as-is.
What happens on empty input?
A non-empty string is required so blank fields are not treated as a successful empty result.
Is the ROT5 digit cipher free?
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/rot5 \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Phone: 555-0199"}'const res = await fetch("https://api.kit.forhosting.com/enc/rot5", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Phone: 555-0199"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/rot5",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Phone: 555-0199"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/rot5", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Phone: 555-0199"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Phone: 555-0199"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/rot5", 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": "Phone: 555-0199"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.rot5",
"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.
Limits
max_chars | 100000 |
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
Empty input is rejected with a clear invalid_input error so callers never treat a blank field as a successful no-op.
What ROT5 does to digits and what it leaves alone
Empty strings are not a valid identity transform here: the API refuses them with invalid_input so a missing form field cannot silently produce another empty string that looks successful.
How to call the API and what comes back
The string must be non-empty and must not exceed the published character limit of one hundred thousand characters. Send a JSON body with one required string field named text. Common aliases also accepted by the solver include input, value, data, message, and s, so existing clients that already label a free-text payload can call this capability without renaming the key. On success the response echoes the original payload under input, sets both result and text to the ROT5-transformed string so either key is convenient for downstream pipelines, reports digits_rotated as the count of ASCII digits that were remapped, non_digits as the count of characters left unchanged, length as the output character count (always equal to the input length), formula as the short mnemonic digit arrow open parenthesis digit plus five close parenthesis mod ten, and message as a one-line English summary of how many digits moved. Failed validation—missing field, wrong type, empty string, or oversize payload—returns invalid_input and is never charged. Pricing is a flat $0.002 per successful request with unit item and zero marginal unit price.
Practical tips, limits, and related searches
Prefer sending the full mixed string rather than stripping punctuation first when the surrounding context matters: phone formats like five five five hyphen zero one nine nine keep their hyphens and spaces while only the digits rotate, which is exactly what puzzle write-ups and light redaction demos usually want. If your source only contains letters, the tool still succeeds and reports zero digits rotated—that is intentional, not an error, because the identity path on non-digits is part of the cipher definition. Prefer this capability when you need a transparent, reversible digit-only substitution for demos, worksheets, or puzzle steps; if you need letter rotation, use a letter-oriented ROT13 tool instead. To decode, call the same endpoint again with the previous result; there is no mode flag to set. Keep payloads under the published maximum length so Worker memory stays bounded. When teaching, pair examples: the digit run zero one two three four five six seven eight nine becomes five six seven eight nine zero one two three four; a phone-style string with hyphens shows punctuation preservation; and an empty string demonstrates the hard invalid_input path. This landing targets people searching for a ROT5 cipher, digit rotator, or online number ROT tool; it is not ROT13 for letters, not a general Caesar cipher with an arbitrary shift, not Base64, and not encryption that provides secrecy against a motivated attacker. Failed tasks that return invalid_input do not consume prepaid balance, which keeps exploratory scripts cheap when clients probe empty fields. Round-trip checks are easy: feed the result back in and assert equality with the original, and confirm that a pure non-digit string leaves both result and input identical while digits_rotated stays zero.
Integration use cases
Pipeline unit tests for digit transforms
Test suites generate known digit strings, assert the fixed (n+5) mod 10 mapping, and include an empty-input invalid_input case as a negative fixture.