Sha256: c60a0c819f0c14a9e9bb7cfdbe4ca7c73def400cdcc77cb134ce9b0a209dd3bc
Contents?: true
Size: 1.9 KB
Versions: 2
Compression:
Stored size: 1.9 KB
Contents
# frozen_string_literal: true module NhtsaVin class Validation TRANSLITERATIONS = { '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 WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2].freeze attr_reader :vin, :valid, :wmi, :vds, :check, :plant, :seq, :error ## # Validates a VIN that it fits both the definition, and that the checksum # is valid. # def initialize(vin) @valid = false if vin.nil? @error = 'Blank VIN provided' return end @vin = vin.strip.upcase if !regex @error = 'Invalid VIN format' return elsif checksum != @check @error = "VIN checksum digit #{@check} failed "\ "to calculate (expected #{checksum})" return else @valid = true end end def valid? @valid end private def regex match_data = %r{ ^(?<wmi>[A-HJ-NPR-Z\d]{3}) (?<vds>[A-HJ-NPR-Z\d]{5}) (?<check>[\dX]) (?<vis>(?<year>[A-HJ-NPR-Z\d]) (?<plant>[A-HJ-NPR-Z\d]) (?<seq>[A-HJ-NPR-Z\d]{6}))$ }ix.match(@vin) if match_data @wmi = match_data[:wmi] @vds = match_data[:vds] @check = match_data[:check] @vis = match_data[:vis] @plant = match_data[:plant] @seq = match_data[:seq] end match_data end def checksum m = @vin.chars.each_with_index.map do |char, i| if char !~ /\D/ char.to_i * WEIGHTS[i] else TRANSLITERATIONS[char.upcase.to_sym] * WEIGHTS[i] end end checksum = m.inject(0, :+) % 11 checksum == 10 ? 'X' : checksum.to_s end end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
nhtsa_vin-0.0.8 | lib/nhtsa_vin/validation.rb |
nhtsa_vin-0.0.7 | lib/nhtsa_vin/validation.rb |