如何验证 VIN 码?

2022-08-30 19:52:29

如何使用 PHP 验证车辆识别号?我只需要检查输入的VIN号是否正确。


答案 1

这是我使用维基百科文章中的示例快速写的东西。

不能保证完美或无错误或超级高效,但应该为您提供一个坚实的起点:

注意:我在下面包含了Confluence提供的编辑,使该过程更加简洁。

function validate_vin($vin) {

    $vin = strtolower($vin);
    if (!preg_match('/^[^\Wioq]{17}$/', $vin)) { 
        return false; 
    }

    $weights = array(8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2);

    $transliterations = array(
        "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++ ) { // loop through characters of VIN
        // add transliterations * weight of their positions to get the sum
        if(!is_numeric($vin{$i})) {
            $sum += $transliterations[$vin{$i}] * $weights[$i];
        } else {
            $sum += $vin{$i} * $weights[$i];
        }
    }

    // find checkdigit by taking the mod of the sum

    $checkdigit = $sum % 11;

    if($checkdigit == 10) { // checkdigit of 10 is represented by "X"
        $checkdigit = "x";
    }

    return ($checkdigit == $vin{8});
}

注意:由于校验和的性质,验证VIN存在一个小百分比错误:

...匹配并不能证明 VIN 是正确的,因为任何两个不同的 VIN 都有 1/11 的几率具有匹配的校验位。

另请注意:将根据上述过程进行验证。您是否要检查这取决于您:11111111111111111

直的(十七个连续的'1')将足以检查数字。这是因为 1 的值乘以 89(权重之和)时,仍为 89。89 % 11 是 1,即校验位。这是测试VIN检查算法的简单方法。

参考资料: http://en.wikipedia.org/wiki/Vehicle_identification_number#Check_digit_calculation


答案 2

这是jordan移植到Javascript的代码版本,希望它对某人有所帮助......

function validate_vin(vin)
{
  function isnumeric(mixed_var) {
    return (typeof(mixed_var) === 'number' || typeof(mixed_var) === 'string') && mixed_var !== '' && !isNaN(mixed_var);
  }
  var pattern = /^[^\Wioq]{17}$/;
  var weights = Array(8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2);
  var 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
  };

  vin = vin.toLowerCase();
  if(!vin.match(pattern)) { return false; }

  var sum = 0;
  for(var i=0; i<vin.length; i++) {
    if(!isnumeric(vin.charAt(i))) {
      sum += transliterations[vin.charAt(i)] * weights[i];
    } else {
      sum += parseInt(vin.charAt(i)) * weights[i];
    }  
  }

  var checkdigit = sum % 11;
  if(checkdigit == 10) { // check digit of 10 represented by X
    checkdigit = 'x';
  }

  return (checkdigit == vin.charAt(8));
}

推荐