-
Notifications
You must be signed in to change notification settings - Fork 558
Generate valid VINs #517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate valid VINs #517
Conversation
Generate VINs that are compliant with FMVSS 115, Part 595 standard.
extend self | ||
|
||
# https://en.wikibooks.org/wiki/Vehicle_Identification_Numbers_(VIN_codes)/World_Manufacturer_Identifier_(WMI) | ||
VALID_WMI_REGIONS = [ ('A'..'C'), ('J'..'Z'), ('1'..'9') ].map(&:to_a).flatten |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe)
VALID_WMI_REGIONS = [ ('A'..'C'), ('J'..'Z'), ('1'..'9') ].map(&:to_a).flatten | |
VALID_WMI_REGIONS = [ *'A'..'C', *'J'..'Z', *'1'..'9' ] |
weighted_sum = generated_vin.chars.each_with_index.map{|char, idx| | ||
(TRANSLITERATION_VALUES[char.to_sym] || char).to_i * POSITION_WEIGHTS[idx] | ||
}.reduce(:+) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe map ... reduce(:+) can replace with sum ...
[2] pry(main)> (1..10).map { |i| i*2 }.reduce(:+)
=> 110
[3] pry(main)> (1..10).sum { |i| i*2 }
=> 110
weighted_sum = generated_vin.chars.each_with_index.map{|char, idx| | |
(TRANSLITERATION_VALUES[char.to_sym] || char).to_i * POSITION_WEIGHTS[idx] | |
}.reduce(:+) | |
weighted_sum = generated_vin.chars.each_with_index.sum { |char, idx| | |
(TRANSLITERATION_VALUES[char.to_sym] || char).to_i * POSITION_WEIGHTS[idx] | |
} |
generated_vin = [ | ||
[ # Manufacturer ID / WMI | ||
fetch_sample(VALID_WMI_REGIONS), | ||
2.times.map{ fetch_sample(VALID_ALPHANUMERIC) }.join | ||
].join, | ||
[ # Vehicle Description | ||
3.times.map{ fetch_sample(VALID_ALPHANUMERIC) }.join, | ||
fetch_sample(VALID_ALPHA), | ||
fetch_sample(VALID_ALPHANUMERIC) | ||
].join, | ||
'0', # check digit placeholder | ||
fetch_sample(VALID_YEAR_CHARS), # Year of Manufacture | ||
fetch_sample(VALID_ALPHANUMERIC), # Plant ID | ||
6.times.map{ rand(10).to_s }.join # Serial number | ||
].join |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think fewer joins lead to better performance.
generated_vin = [ | |
[ # Manufacturer ID / WMI | |
fetch_sample(VALID_WMI_REGIONS), | |
2.times.map{ fetch_sample(VALID_ALPHANUMERIC) }.join | |
].join, | |
[ # Vehicle Description | |
3.times.map{ fetch_sample(VALID_ALPHANUMERIC) }.join, | |
fetch_sample(VALID_ALPHA), | |
fetch_sample(VALID_ALPHANUMERIC) | |
].join, | |
'0', # check digit placeholder | |
fetch_sample(VALID_YEAR_CHARS), # Year of Manufacture | |
fetch_sample(VALID_ALPHANUMERIC), # Plant ID | |
6.times.map{ rand(10).to_s }.join # Serial number | |
].join | |
generated_vin = [ | |
# Manufacturer ID / WMI | |
fetch_sample(VALID_WMI_REGIONS), | |
*fetch_sample(VALID_ALPHANUMERIC, count: 2), | |
# Vehicle Description | |
*fetch_sample(VALID_ALPHANUMERIC, count: 3), | |
fetch_sample(VALID_ALPHA), | |
fetch_sample(VALID_ALPHANUMERIC), | |
'0', # check digit placeholder | |
fetch_sample(VALID_YEAR_CHARS), # Year of Manufacture | |
fetch_sample(VALID_ALPHANUMERIC), # Plant ID | |
*fetch_sample(0..9, count: 6) # Serial number | |
].join |
note: I know 6.times.map{ rand(10).to_s }
is not same result with fetch_sample(0..9, count: 6)
. but That will be not problem in this case.
vin = FFaker::Vehicle.vin | ||
|
||
assert_match(/\A[A-Z0-9]{17}\z/, vin) | ||
assert_not_match(/[IOQ]/, vin) # VINs can't have these letters | ||
assert_includes(FFaker::Vehicle::VIN::VALID_ALPHA, vin[6]) # passenger vehicle designator | ||
assert_includes(FFaker::Vehicle::VIN::VALID_YEAR_CHARS, vin[9]) # check year character |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice test 👏🏽
I will merge this and apply reviews. Thank you for this PR. (And sorry for late 🙈 ) |
Issue #310
Generate VINs that are compliant with FMVSS 115, Part 595 standard. Uses designated character set and format, and includes valid Check Digit.
The support code + constants for the VIN code is namespaced in to it's own module to avoid cluttering up the main file.
Note
test/test_vehicle.rb#test_vin
could be brittle and the expected checksum could change if they was the VIN is generatedFFaker::Vehicle::VIN::vin
is changed.