1. Use the check digit before the registry search
A failed check stops a bad identifier early. A pass lets you continue to the live record. It does not approve the company.
Detection rate = share of deliberately corrupted codes that fail the scheme’s own check equation. Substitutions and transpositions are exhaustive over 2,000 generated codes per scheme; double errors are fixed-seed Monte-Carlo.
| Error class | USCI (GB 32100-2015) | VIN (49 CFR 565) |
|---|---|---|
| Single-character substitution (exhaustive) | 100% (1,080,000 of 1,080,000) | 92.52% (1,006,623 of 1,088,000) |
| Two-position transposition, all positions | 99.34% | 88.06% |
| Transpositions within data positions only | 100% | 86.75% |
| Random double substitution (Monte-Carlo) | 96.41% | 91.52% |
USCI swap misses involved the check character itself. For VIN, a separate 500-code run traced all 20,364 missed single substitutions to characters with the same numeric value, such as A/J and S/2.
2. Why the designs differ, and what that means at a desk
- USCI uses distinct weights and a prime modulus. GB 32100-2015 works modulo 31. A single changed character, or two differing characters swapped within the data positions, changes its check equation.
- VIN maps different characters to the same value. A and J both map to 1; S and 2 both map to 2. Swapping one for the other can leave the checksum unchanged.
- Start with a local check. Use the USCI checker to spot errors before a registry search. For a trailer VIN, compare the code on the documents and manufacturer record.
- A pass proves only that the check equation holds. A code may still be mistyped or fabricated. Check the company’s registered identity and status separately.
3. Method, and what this study cannot say
- Codes: 2,000 per scheme, generated with a fixed-seed PRNG (mulberry32, seed 20260809) so the runs are reproducible. USCI codes use realistic authority/division prefixes; the prefix distribution does not affect detection, which depends only on character values and positions.
- Implementations: the USCI algorithm is imported unchanged from this site’s public checker; the VIN algorithm follows 49 CFR 565.15 and validates against the sample VIN published in NHTSA’s manufacturer handbook (1M8GDM9AXKP042788, check digit X).
- Error model limits: The experiment uses mechanical errors, not observed human typing. It tries every alternative character and differing position pair within the generated codes. Real typing rates may differ; the random double-error trials are not exhaustive.
- Scope limits: this is a study of two checksum algorithms only. It says nothing about any company, vehicle or document. It also does not compare the two identifier systems as a whole: the VIN encodes manufacturing facts that the USCI does not attempt to capture.
A failed check is a reason to re-copy the identifier from its source. This experiment did not query company or vehicle records and cannot show what is on file.
Citing this study
You are welcome to quote or reproduce these figures, including commercially, provided the date I checked it, the seed and the stated limits travel with them. Machine-readable evidence with full counts: the result file. Primary sources: GB 32100-2015 (standard listing; checked 9 August 2026) and 49 CFR Part 565 (checked 9 August 2026). More measured data: the research index.
Archived copies, each with its own DOI, resolving independently of this site: Zenodo · Harvard Dataverse · figshare.
A citation with everything it needs:
Currawong, “How much does a check digit protect you? I measured”, 2.9 million injected transcription errors through the USCI (GB 32100-2015) and VIN (49 CFR 565) check algorithms with a fixed seed, 9 August 2026.
https://currawongweb.com/verify/does-usci-check-digit-catch-typos/Dataset:https://doi.org/10.5281/zenodo.21867383
BibTeX
@dataset{currawong_verify_check_digit_protection_study_2026,
author = {Bao L. Zhou},
title = {{Check-digit error-detection rates: USCI (GB 32100-2015) vs VIN (49 CFR 565)}},
year = {2026},
publisher = {Zenodo},
doi = {10.5281/zenodo.21867383},
url = {https://doi.org/10.5281/zenodo.21867383}
}