Completed
Push — master ( 74e6b2...ff067b )
by Ronan
13s
created

VinNA::validate()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 9.0488
c 0
b 0
f 0
cc 5
nc 7
nop 1
1
<?php
2
3
namespace IsoCodes;
4
5
/**
6
 * Class VisNA, validating VIN numbers in North America.
7
 *
8
 * A vehicle identification number (VIN) (also called a chassis number or frame number) is a unique code,
9
 * including a serial number, used by the automotive industry to identify
10
 * individual motor vehicles, towed vehicles, motorcycles, scooters and mopeds,
11
 * as defined in ISO 3779 (content and structure) and ISO 4030 (location and attachment).
12
 *
13
 * @source  https://en.wikipedia.org/wiki/Vehicle_identification_number#North_American_check_digits
14
 */
15
class VinNA implements IsoCodeInterface
16
{
17
    /**
18
     * VIN validation.
19
     *
20
     * @param mixed $vin
21
     *
22
     * @return bool
23
     */
24
    public static function validate($vin)
25
    {
26
        $vin = strtolower($vin);
27
        if (!preg_match('/^[^\Wioq]{17}$/', $vin)) {
28
            return false;
29
        }
30
31
        $weights = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];
32
33
        $letterVal = [
34
            'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4,
35
            'e' => 5, 'f' => 6, 'g' => 7, 'h' => 8,
36
            'j' => 1, 'k' => 2, 'l' => 3, 'm' => 4,
37
            'n' => 5, 'p' => 7, 'r' => 9, 's' => 2,
38
            't' => 3, 'u' => 4, 'v' => 5, 'w' => 6,
39
            'x' => 7, 'y' => 8, 'z' => 9,
40
        ];
41
42
        $sum = 0;
43
44
        for ($i = 0; $i < strlen($vin); ++$i) {
45
            if (!is_numeric($vin[$i])) {
46
                $sum += $letterVal[$vin[$i]] * $weights[$i];
47
            } else {
48
                $sum += $vin[$i] * $weights[$i];
49
            }
50
        }
51
52
        $check = $sum % 11;
53
        if (10 == $check) {
54
            $check = 'x';
55
        }
56
57
        return $check == $vin[8];
58
    }
59
}
60