Vehicle Identification Numbers (VINs) are used to uniquely identify motor vehicles. They consist of 17 characters that do not include the letters I, O or Q.

The first three characters uniquely identify the manufacturer, make and type of vehicle. A manufacturer that builds less than 500 vehicles per year uses a 9 as the third digit and the 12th, 13th and 14th position of the VIN for a second part of the identification. Some manufacturers use the third character as a code for a vehicle category (e.g., bus or truck).

Table of contents
1 Examples
2 Model Year Encoding
3 Check Digit Calculation
4 Example
5 Perl Source Code

Examples

first character

  • 1 or 4: USA
  • 2: Canada
  • 3: Mexico
  • J: Japan
  • K: Korea
  • S: England
  • W: Germany
  • Z: Italy

second character

  • 1: Chevrolet
  • 2 or 5: Pontiac
  • 3: Oldsmobile
  • 4: Buick
  • 6: Cadillac
  • 7: GM Canada
  • 8: Saturn
  • A: Audi or Jaguar
  • B: BMW or Dodge
  • C: Chrysler
  • D: Mercedes Benz
  • F: Ford
  • G: General Motors
  • H: Honda
  • L: Lincoln
  • M: Mercury or Hyundai
  • N: Nissan
  • P: Plymouth
  • S: VW of Brazil
  • T: Toyota
  • V: Volkswagen or Volvo
  • Y: Mazda

The second section consists of five characters (VIN positions 4-8) and identifies the attributes of the vehicle. For each type of vehicle (passenger cars, MPVs, trucks, buses, trailers, motorcycles, incomplete vehicles other than trailers) different information is required. For cars, MPVs and light trucks, the first two characters of this section are alphabetic, the third and fourth numeric and the fifth alphanumeric.

The third section consists of one character that is the check digit, calculated over the other 16 characters of the VIN. This character can be numeric or the letter X.

The fourth section consists of eight characters on positions 10-17 of the VIN. The last five are numeric for cars, MPVs and light trucks and the last four are numeric for all other vehicles. The first character represents the vehicle model year and the second character represents the plant of manufacture. The third through eighth characters are a sequential production number for manufacturers producing more than 500 vehicles per year. For smaller manufacturers, the sixth, seventh and eight position represent the sequential production number.

Model Year Encoding

Besides the three letters that are not allowed in the VIN itself (I, O and Q), the letter U and the digit 0 are not used for the year code. Note that the year code can be the calendar year in which a vehicle is built, or a model or type year allocated by the manufacturer. The year 1980 is encoded as "A", and subsequent years increment through the allowed letters, so that "Y" represents the year 2000. 2001 through 2009 are encoded as the digits 1 through 9.

Check Digit Calculation

Firstly, find the numerical value associated with each letter in the VIN. (I, O and Q are not allowed.) Digits use their own values.

A: 1J: 1 
B: 2K: 2S: 2
C: 3L: 3T: 3
D: 4M: 4U: 4
E: 5N: 5V: 5
F: 6 W: 6
G: 7P: 7X: 7
H: 8 Y: 8
 R: 9Z: 9

Secondly, look up the weight factor for each position in the VIN except the 9th (the position of the check digit).
1st: ×85th: ×410th: ×914th: ×5
2nd: ×76th: ×311th: ×815th: ×4
3rd: ×67th: ×212th: ×716th: ×3
4th: ×58th: ×1013th: ×617th: ×2

Thirdly, multiply the numbers and the numerical values of the letters by their assigned weight factor, and sum the resulting products. Divide the sum of the products by 11. The remainder is the check digit. If the remainder is 10, the check digit is the letter X.

Example

Consider the hypothetical VIN 1M8GDM9A_KP042788, where the underscore will be the check digit.
    VIN: 1  M  8  G  D  M  9  A  _  K  P  0  4  2  7  8  8
  Value: 1  4  8  7  4  4  9  1  0  2  7  0  4  2  7  8  8
 Weight: 8  7  6  5  4  3  2 10  0  9  8  7  6  5  4  3  2
Products: 8 28 48 35 16 12 18 10 0 18 56 0 24 10 28 24 16

The sum of all 16 products is 351. Dividing by 11 gives a remainder of 10, so the check digit is "X" and the complete VIN is 1M8GDM9AXKP042788.

Perl Source Code

sub calcVINcheckdigit {
 my %lettervalue = ("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, "1", 1,
                    "2", 2, "3", 3, "4", 4, "5", 5,
                    "6", 6, "7", 7, "8", 8, "9", 9, "0", 0);

my @positionweight = (8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2);

my @vinchar = split(//, $_[0]); my $total = 0; for (my $ctr = 0; $ctr < 17; $ctr++) { $total += $lettervalue{$vinchar[$ctr]} * $positionweight[$ctr]; } return (($total % 11) == 10) ? "X" : ($total % 11);

}