File: vehicle.rb

package info (click to toggle)
ruby-ffaker 2.23.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,776 kB
  • sloc: ruby: 12,788; makefile: 8; sh: 1
file content (133 lines) | stat: -rw-r--r-- 3,910 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# frozen_string_literal: true

module FFaker
  module Vehicle
    module VIN
      extend ModuleUtils
      extend self

      # https://en.wikibooks.org/wiki/Vehicle_Identification_Numbers_(VIN_codes)/World_Manufacturer_Identifier_(WMI)
      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 # 2005-2039

      # https://en.wikibooks.org/wiki/Vehicle_Identification_Numbers_(VIN_codes)/Check_digit
      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

      # Generate a VIN that is compliant with specifications of US Title 49 Section 565.15
      # https://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.
      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
    end

    extend ModuleUtils
    extend self

    DRIVETRAINS = %w[4WD 4X4 AWD FWD RWD].freeze
    YEARS = Array('1900'..(::Time.now.year + 1).to_s).freeze
    TRANSMISSIONS_ABBR = %w[AT MT AM CVT].freeze
    CYLINDERS = %w[2 5 6 8].freeze

    def base_color
      FFaker::Color.name
    end

    def drivetrain
      fetch_sample(DRIVETRAINS)
    end

    def make
      fetch_sample(MAKES_LIST)
    end

    def manufacturer_color(count = 2)
      # Take two prefixes because it's more fun than one
      (fetch_sample(COLOR_PREFIXES, count: count) + [base_color]).join(' ')
    end
    alias mfg_color manufacturer_color

    def model
      fetch_sample(MODELS_LIST)
    end

    def trim
      fetch_sample(TRIMS_LIST)
    end

    def vin
      VIN.vin
    end

    def year
      fetch_sample(YEARS)
    end

    def transmission
      fetch_sample(TRANSMISSIONS_LIST)
    end

    def transmission_abbr
      fetch_sample(TRANSMISSIONS_ABBR)
    end

    def engine_cylinders
      fetch_sample(CYLINDERS)
    end

    def engine_displacement
      fetch_sample(DISPLACEMENTS_LIST)
    end

    def fuel_type
      fetch_sample(FUEL_TYPES_LIST)
    end

    def interior_upholstery
      fetch_sample(UPHOLSTERY_LIST)
    end
  end
end