Module: FFaker::Vehicle::VIN

Extended by:
ModuleUtils, VIN
Included in:
VIN
Defined in:
lib/ffaker/vehicle.rb

Constant Summary collapse

VALID_WMI_REGIONS =
[*'A'..'C', *'J'..'N', 'P', *'R'..'Z', *'1'..'9'].freeze
VALID_YEAR_CHARS =
%w[
  5 6 7 8 9 A B C D E F G H J K L M N P R S T V W X Y 1 2 3 4 5 6 7 8 9
].freeze
TRANSLITERATION_VALUES =
{
  'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8,
  'J' => 1, 'K' => 2, 'L' => 3, 'M' => 4, 'N' => 5, 'P' => 7, 'R' => 9,
  'S' => 2, 'T' => 3, 'U' => 4, 'V' => 5, 'W' => 6, 'X' => 7, 'Y' => 8, 'Z' => 9
}.freeze
POSITION_WEIGHTS =
[8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2].freeze
VALID_ALPHA =
TRANSLITERATION_VALUES.keys
VALID_ALPHANUMERIC =
[*VALID_ALPHA, *'1'..'9'].freeze

Instance Method Summary collapse

Methods included from ModuleUtils

const_missing, k, luhn_check, underscore, unique

Methods included from RandomUtils

#fetch_sample, #rand, #shuffle

Instance Method Details

#vinObject

Generate a VIN that is compliant with specifications of US Title 49 Section 565.15 www.govinfo.gov/content/pkg/CFR-2019-title49-vol6/xml/CFR-2019-title49-vol6-part565.xml#seqnum565.15

Position Meaning 1-3 Manufacturer ID aka WMI (alpha and digits) 4-8 Vehicle Description (“For passenger cars ..[position 7].. shall be alphabetic”) 9 Check Digit (0-9 or “X”) 10 Year (see VIN_VALID_YEARS) 11 Plant of manufacture (alpha and digits) 12-17 Serial number (digits only)

I, O and Q are NOT allowed. VIN_VALID_ALPHA has valid alpha characters.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ffaker/vehicle.rb', line 39

def vin
  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
    FFaker.numerify('######') # Serial Number
  ].join

  # Calculate the Check Digit
  weighted_sum = generated_vin.chars.each_with_index.sum do |char, idx|
    (TRANSLITERATION_VALUES[char] || char).to_i * POSITION_WEIGHTS[idx]
  end

  check_digit = weighted_sum % 11
  check_digit = 'X' if check_digit == 10
  generated_vin[8] = check_digit.to_s

  generated_vin
end