Since #2765, vin() has the correct length and excludes I/O/Q, but position 9 — the check digit under ISO 3779 / 49 CFR §565 — is generated as a free alphanumeric: it is often not even in the legal [0-9X] set for that position, and never computed. As a result, any test that feeds a generated VIN into a validator has to hardcode fixtures like WBADT43452G012345 instead of using faker.
Proposal: compute position 9 with the standard algorithm (transliteration table + weights, sum mod 11, value 10 → X). Since position 9 carries weight 0, the digit can be computed over the VIN generated exactly as today and spliced in — the number of random draws stays identical, so only vin()'s own seeded output changes, not subsequent values in a seeded sequence.
Precedents: faker already computes check digits where validators exist — Luhn for card numbers, mod-97 for IBAN — and faker-ruby merged this exact fix (faker-ruby/faker#2633). Prior VIN accuracy fixes here: #319, #540 → #2765.
Regional note: the check digit is mandatory under the North American rule and regional under ISO 3779, so a computed digit is also a plausible position-9 value elsewhere — this strictly increases realism.
Seeded vin() snapshots would change (as #2765 did). Happy to open the PR (~40 lines + tests) if this is welcome.
Since #2765,
vin()has the correct length and excludes I/O/Q, but position 9 — the check digit under ISO 3779 / 49 CFR §565 — is generated as a free alphanumeric: it is often not even in the legal[0-9X]set for that position, and never computed. As a result, any test that feeds a generated VIN into a validator has to hardcode fixtures likeWBADT43452G012345instead of using faker.Proposal: compute position 9 with the standard algorithm (transliteration table + weights, sum mod 11, value 10 →
X). Since position 9 carries weight 0, the digit can be computed over the VIN generated exactly as today and spliced in — the number of random draws stays identical, so onlyvin()'s own seeded output changes, not subsequent values in a seeded sequence.Precedents: faker already computes check digits where validators exist — Luhn for card numbers, mod-97 for IBAN — and faker-ruby merged this exact fix (faker-ruby/faker#2633). Prior VIN accuracy fixes here: #319, #540 → #2765.
Regional note: the check digit is mandatory under the North American rule and regional under ISO 3779, so a computed digit is also a plausible position-9 value elsewhere — this strictly increases realism.
Seeded
vin()snapshots would change (as #2765 did). Happy to open the PR (~40 lines + tests) if this is welcome.