Skip to content

Commit

Permalink
Merge pull request #168 from ronanguilloux/vin
Browse files Browse the repository at this point in the history
+1 Vin validation
  • Loading branch information
ronanguilloux committed Feb 14, 2021
2 parents 74e6b22 + 65952e5 commit ff067be
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -37,6 +37,9 @@ $isCUSIP = Cusip::validate('037833100'); // Apple Inc. (AAPL)

// Checking your iPhone device is valid?
$isDevice = Imei::validate('352066060926230');

// Selling Your Honda Civic?
$isVin = VinNA::validate('1HGBH41JXMN109186');
```


Expand All @@ -56,6 +59,7 @@ $isDevice = Imei::validate('352066060926230');
* ISMN - International Standard Music Number
* ISWC - International Standard Musical Work Code
* IMEI - International Mobile Equipment Identity
* VIN - Vehicle Identification Number – ISO 3779 & ISO 4030

### Public Administrations

Expand Down
1 change: 1 addition & 0 deletions src/IsoCodes/Sedol.php
Expand Up @@ -4,6 +4,7 @@

/**
* @see https://en.wikipedia.org/wiki/SEDOL
* Stock Exchange Daily Official List
*
* @author Sullivan Senechal <soullivaneuh@gmail.com>
*/
Expand Down
59 changes: 59 additions & 0 deletions src/IsoCodes/VinNA.php
@@ -0,0 +1,59 @@
<?php

namespace IsoCodes;

/**
* Class VisNA, validating VIN numbers in North America.
*
* A vehicle identification number (VIN) (also called a chassis number or frame number) is a unique code,
* including a serial number, used by the automotive industry to identify
* individual motor vehicles, towed vehicles, motorcycles, scooters and mopeds,
* as defined in ISO 3779 (content and structure) and ISO 4030 (location and attachment).
*
* @source https://en.wikipedia.org/wiki/Vehicle_identification_number#North_American_check_digits
*/
class VinNA implements IsoCodeInterface
{
/**
* VIN validation.
*
* @param mixed $vin
*
* @return bool
*/
public static function validate($vin)
{
$vin = strtolower($vin);
if (!preg_match('/^[^\Wioq]{17}$/', $vin)) {
return false;
}

$weights = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];

$letterVal = [
'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,
];

$sum = 0;

for ($i = 0; $i < strlen($vin); ++$i) {
if (!is_numeric($vin[$i])) {
$sum += $letterVal[$vin[$i]] * $weights[$i];
} else {
$sum += $vin[$i] * $weights[$i];
}
}

$check = $sum % 11;
if (10 == $check) {
$check = 'x';
}

return $check == $vin[8];
}
}
33 changes: 33 additions & 0 deletions tests/IsoCodes/Tests/VinNATest.php
@@ -0,0 +1,33 @@
<?php

namespace IsoCodes\Tests;

/**
* Class CifTest.
*
* @covers \IsoCodes\VinNA
*/
class VinNATest extends AbstractIsoCodeInterfaceTest
{
/**
* {@inheritdoc}
*/
public function getValidValues()
{
return [
['1M8GDM9AXKP042788'], // https://en.wikipedia.org/wiki/Vehicle_identification_number#Worked_example
['WAUZZZF49HA036784'], // https://www.rac.co.uk/drive/advice/buying-and-selling-guides/vin-number/
['1HGBH41JXMN109186'], // https://www.yourmechanic.com/article/how-to-decode-a-vin-vehicle-identification-number-by-jason-unrau
];
}

/**
* {@inheritdoc}
*/
public function getInvalidValues()
{
return [
['1M8GDM9AYKP042788'], // wrong check
];
}
}

0 comments on commit ff067be

Please sign in to comment.