Question

Quelqu'un sait-il un code de validation Vehicle Identification Number ( wiki ) écrit en PHP? Je dois juste vérifier si le numéro de vin saisi est correct ou non?

Était-ce utile?

La solution

de quelque chose de ici j'ai écrit réel à l'aide rapide l'exemple dans l'article de wikipedia.

Non garanti parfait ou bug ou super efficace, mais devrait vous fournir un point de départ solide:

Remarque : J'inclus les modifications fournies par http://en.wikipedia.org/wiki/Vehicle_identification_number#Check_digit_calculation

Autres conseils

Voici une version du code par jordan porté sur Javascript, espérons qu'il est utile à quelqu'un ...

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));
}

Il est "VIN." "VIN Number" = "Numéro d'identification du véhicule Numéro", qui n'a pas de sens.

Vous pouvez voir une définition de la structure de VINs ici:
http://en.wikipedia.org/wiki/Vehicle_identification_number

Et vous pouvez travailler à partir de là, ou vous pouvez saisir ici ce script:
http://www.geekpedia.com/code29_Check-if-VIN -Nombre-est-valid.html


Voici une version améliorée de la fonction affichée par Jordan:

$vin = "1M8GDM9AXKP042788";

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});
}

J'ai eu récemment d'écrire une classe de validation VIN avec PHP. J'ai posté ma classe pour tout le monde à utiliser à: http://dev.strategystar.net/2012/05/ validate-vin-contrôle-avec-php /

class VIN
{
    public static $transliteration = 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,
    );

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

    /***
     * The checksum method is used to validate whether or not a VIN is valid
     * It will return an array with two keys: status and message
     * The "status" will either be boolean TRUE or FALSE
     * The "message" will be a string describing the status
     */
    public static function checksum($vin)
    {
        $vin = strtoupper($vin);
        $length = strlen($vin);
        $sum = 0;

        if($length != 17)
        {
            return array('status'=>false, 'message'=>'VIN is not the right length');
        }

        for($x=0; $x<$length; $x++)
        {
            $char = substr($vin, $x, 1);

            if(is_numeric($char))
            {
                $sum += $char * self::$weights[$x];
            }
            else
            {
                if(!isset(self::$transliteration[$char]))
                {
                    return array('status'=>false, 'message'=>'VIN contains an invalid character.');
                }

                $sum += self::$transliteration[$char] * self::$weights[$x];
            }
        }

        $remainder = $sum % 11;
        $checkdigit = $remainder == 10 ? 'X' : $remainder;

        if(substr($vin, 8, 1) != $checkdigit)
        {
            return array('status'=>false, 'message'=>'The VIN is not valid.');
        }

        return array('status'=>true, 'message'=>'The VIN is valid.');
    }
}

Merci à tous pour l'algorithme etc que je vois est sur Wikipedia. Ceci est la version que je mets ensemble sur la base des commentaires ci-dessus. Remarque, il y a des problèmes avec les versions ci-dessus, pour ex ce 00000000000354888 OK retourne pour un vin. Je pris ce qui était au-dessus et a ajouté une option pour vérifier première année si <1980, supposons que ce n'est pas un vin réel 17digit (devoir), et même s'il y a des séquences d'un seul caractère, supposons invalide. Cela est suffisant pour mes besoins que je compare par rapport aux valeurs qui sont remplis avec des 0 sinon 17 de longueur. Je sais aussi la valeur de l'année, donc si je vérifie que je peux accélérer le code en sautant le chèque de vin (oui je aurais pu mettre cela en avant la fonction) lol bye!.

  <?php
  /*
  =======================================================================================
  PURPOSE: VIN Validation (Check-digit validation is compulsory for all road vehicles sold in North America.)
  DETAILS: Validates 17 digit VINs by checking their formatting
  USAGE:  returns boolean or returns an array with a detailed message
  COMMENTS: This could be made more robust by checking the country codes etc..
  MORE INFO: https://en.wikipedia.org/wiki/Vehicle_identification_number
  =======================================================================================
  */

  class vinValidation {

public static $transliteration = 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,
);

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

public function validateVIN($vin, $ret_array_status = false, $year = null) {

    //validates US/NA 1980>= VINs, if before 1980, no vin standards, this returns false
    if (!empty($year) && preg_match("/^[0-9]{4}/", $year)) {
        if ($year < 1980) return ($ret_array_status ? array('status' => false, 'message' => 'Unable to check VIN, pre-dates 1980.') : false);
    }

    $vin_length = 17; // US vin requirements >= 1980
    $vin = strtoupper(trim($vin));
    $sum = 0;

     //if (!preg_match('/^[^\Wioq]{17}$/', $vin))
    //return ($ret_array_status ? array('status'=>false, 'message'=>'VIN is not valid, not the right length.') : false);

    if (!preg_match('/^[A-HJ-NPR-Z0-9]{17}$/', $vin))
    return ($ret_array_status ? array('status'=>false, 'message'=>'VIN is not valid, VIN formatting is incorrect.') : false);

    if (preg_match('/(\w)\1{5,}/', $vin))
    return ($ret_array_status ? array('status'=>false, 'message'=>'VIN contains invalid repeating character sequence.') : false);

    for($x=0; $x < $vin_length; $x++) {
        $char = substr($vin, $x, 1);
        if(is_numeric($char)) {
            $sum += $char * self::$weights[$x];
        } else {
            if(!isset(self::$transliteration[$char]))
            return ($ret_array_status ? array('status'=>false, 'message'=>'VIN contains an invalid character.') : false);
            $sum += self::$transliteration[$char] * self::$weights[$x];
        }
    }
    $remainder = $sum % 11;
    $checkdigit = $remainder == 10 ? 'X' : $remainder;

    //echo " sum:".$sum." remain:".$remainder." check dig:".$checkdigit."\n";

    if(substr($vin, 8, 1) != $checkdigit)
    return ($ret_array_status ? array('status'=>false, 'message'=>'The VIN is not valid, failed checksum.') : false);

    // all is good return true or a value and status.
    return ($ret_array_status ? array('status'=>true, 'message'=>'The VIN is valid, passed checksum.') : true);
}


  }

TEST:

  $vinClass = new vinValidation();

  // not long enough not val
  var_dump($vinClass->validateVIN('1I345678123456789', false, 2000));
  var_dump($vinClass->validateVIN('1I345678123456789'));

  echo "-----------------------------------------------------------\n";
  // not valid
  var_dump($vinClass->validateVIN('00000000012870842', true));
  var_dump($vinClass->validateVIN('00000000012870842', 1968)); //assumes faulty by year
  var_dump($vinClass->validateVIN('00000000012870842'));

  echo "-----------------------------------------------------------\n";
  // not valid
  var_dump($vinClass->validateVIN('00000000000354888', true));
  var_dump($vinClass->validateVIN('00000000000354888'));

  echo "-----------------------------------------------------------\n";
  // Fails Checksum test
  var_dump($vinClass->validateVIN('368TU79MXH4763452',false,2000));
  var_dump($vinClass->validateVIN('368TU79MXH4763452'));

  echo "-----------------------------------------------------------\n";
  // yachtzee, (returns true or array) !
  var_dump($vinClass->validateVIN('WP1AF2A56GLB91679',true));
  var_dump($vinClass->validateVIN('WP1AF2A56GLB91679'));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top