UIC wagon number check digit
A wagon whose first eleven digits are 21812471217 gets check digit 3, so its full UIC number reads 218124712173. Paste a complete twelve-digit number instead and you see at once whether the last digit fits. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Number
- 21812471217
- Calculation mode
- Compute
- Input
- 21812471217
- Check digit
- 3
- Vehicle number
- 218124712173
Railway operators, wagon owners, and logistics systems identify freight and passenger stock with a twelve-digit UIC European vehicle number. Eleven of those digits encode type, country, and serial identity; the twelfth is a self-check digit derived from a fixed alternating two-one weighting so that a single mistype or transposition is far more likely to fail than to look like a different valid vehicle.
How the UIC check digit is calculated
The UIC and European vehicle numbering rules define a deterministic check digit over the first eleven digits of the twelve-digit vehicle number. The eleven folded values are summed. The check digit is ten minus that sum modulo ten, taken modulo ten again so that a sum already divisible by ten yields check digit zero.
Appending that single digit produces the full twelve-digit number that appears on the wagon body and in fleet databases, often printed with grouping spaces and a hyphen before the check digit. Validation is the inverse: recompute the expected digit from the first eleven characters and compare it to the twelfth.
Where UIC check digits fit real railway workflows
Rolling-stock owners and keepers assign serials within a class and country code; before paint, plates, and TAF/TSI registers are updated they must append the correct check digit so partners and trackside systems accept the identity on first read. Workshop and maintenance systems import keeper CSV files of twelve-digit numbers and should reject rows whose check digit no longer matches, which catches both human edits and off-by-one bugs in upstream generators.
Intermodal and terminal gate applications that let clerks type a wagon number can validate on blur and block moves until valid is true, reducing failed EDI exchanges and yard mismatches. Do not treat a passing check digit as proof of allocation, keeper rights, or type-code correctness — it only proves the twelve-digit string is arithmetically well formed under the UIC alternating two-one rule, the same honesty bar you apply to any industrial checksum.
What you can do with it
Audit keeper and RIV exchange files
Batch-validate every twelve-digit vehicle number in a partner CSV or EDI export and quarantine rows whose check digit no longer matches the recomputed expected value.
FAQ
What is a UIC wagon number check digit?
It is the twelfth digit of a European railway vehicle number, computed from the first eleven digits with alternating weights of 2 and 1 and a Luhn-style digit-sum fold so single-digit typos are far more likely to fail validation than to look like another vehicle.
Is the UIC wagon number check digit tool free?
The browser tool is free and runs locally.
How is the UIC wagon check digit calculated?
Starting from the left, the eleven digits are multiplied by 2, 1, 2, 1 and so on. Any product above 9 is replaced by the sum of its two digits, everything is added up, and the check digit is what takes that sum to the next multiple of ten (0 if it already is one).
Does a valid check digit prove the wagon is registered?
No. It only shows that the twelve digits are arithmetically consistent. It says nothing about whether the number was allocated, who the keeper is or whether the type code is right.
Can I paste the number with spaces, hyphens or dots?
Yes. The spaces, hyphen and dots of the usual printed layout are removed before the check. Letters and other symbols are refused, so a stray character cannot slip through unnoticed.
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/uic-wagon \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"number":"21812471217"}'const res = await fetch("https://api.kit.forhosting.com/enc/uic-wagon", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"number": "21812471217"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/uic-wagon",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"number": "21812471217"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/uic-wagon", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"number":"21812471217"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"number":"21812471217"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/uic-wagon", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"number": "21812471217"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.uic_wagon",
"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
This capability computes that check digit from an eleven-digit payload, or validates a complete twelve-digit number and reports whether the stored trailing digit matches the recomputed value. Spaces, hyphens, and dots used in the common printed layout are stripped before the arithmetic runs; letters and other non-digits are rejected with a clear invalid_input error. Run it free in the browser or call the KIT API at the published price; both paths use the same pure integer algorithm with no network round-trip and no stored vehicle registers.
How the UIC check digit is calculated
Number those payload positions from the left starting at index zero: each digit is multiplied by weight two when the index is even, and by weight one when the index is odd, then any product greater than nine is folded by summing its decimal digits (the same Luhn-style fold used in related mod-10 schemes). Because the algorithm is pure integer arithmetic with fixed weights, the same payload always produces the same check digit on every platform — browser, Worker, or offline test harness — which is why the capability ships as a tier-A parse engine rather than a model call.
How to compute a check digit or validate a full vehicle number
Mode validate expects exactly twelve digits after stripping. Empty strings, missing number, invalid mode values, and wrong lengths (for example ten or thirteen digits) fail before any weighted sum runs and are not billed. Send a number field that contains the payload or full vehicle digits. Optional spaces, hyphens, and dots are stripped so forms can accept the common display layout such as twenty-one eighty-one groups with a trailing dash and check digit; letters and other symbols are rejected as non-numeric input with invalid_input so a form never accepts a silently cleaned value that still looks wrong. Mode compute is the default: provide exactly eleven payload digits after stripping; the engine returns check_digit as a one-character string, vehicle_number as the eleven digits plus that check digit, and length twelve. The response reports valid true when the trailing digit matches the recomputed expected_check_digit, and always includes payload (the first eleven digits), check_digit as submitted, expected_check_digit, and the canonical vehicle_number built from payload plus expected digit. That shape makes it easy to show “you typed X, expected Y” in a fleet UI without a second request. Because the path is pure parse with no clock, random source, or network, the same input always yields the same JSON on the free browser tool and on the API. At $0.002 per successful request you can protect bulk fleet imports, RIV exchange files, and partner EDI audits without negotiating a custom tier. Prefer compute when you mint or complete a new serial block; prefer validate when you receive a full number from a scanner, a CSV, or a keeper-change form and need a boolean gate before storing the asset.
Where UIC check digits fit real railway workflows
Integration tests and data-quality jobs recompute expected_check_digit for every vehicle column in an export and quarantine mismatches before they reach national or international registers. Label printers that compose stencils from eleven-digit payloads call compute mode once per vehicle and place vehicle_number under the marking graphic.
Integration use cases
Complete an eleven-digit payload for plates and paint
Take the type, country, and serial digits (eleven total), call compute mode, and print vehicle_number on the wagon so the marking carries a partner-valid UIC check digit.
Validate scanned or typed wagon numbers at entry
When a handheld scanner or form submits twelve digits, call validate mode and block fleet or yard updates when valid is false, showing expected_check_digit to fix a mistype.
Technical questions
How do I compute a UIC check digit with this API?
POST with number set to exactly eleven digits (spaces, hyphens, and dots optional) and mode compute (or omit mode). The response includes check_digit and vehicle_number (the full twelve-digit code).
How do I validate a full twelve-digit vehicle number?
POST with the twelve-digit string and mode validate. The response includes valid, check_digit, expected_check_digit, payload, and the canonical vehicle_number.
What happens with letters, wrong lengths, or bad separators?
Spaces, hyphens, and dots are stripped; remaining non-digits and lengths other than eleven (compute) or twelve (validate) are rejected with invalid_input. Failed validation tasks are not billed.