php - vehiculo - verificar vin toyota
Código de validación del número de VIN de PHP (5)
¿Alguien sabe algún código de validación de Vehicle Identification Number
( wiki ) escrito en PHP? ¿Solo necesito verificar si el número de vin ingresado es correcto o no?
Aquí hay algo que escribí muy rápido usando el ejemplo en el artículo de wikipedia.
No se garantiza que sea perfecto, libre de errores o súper eficiente, pero debería proporcionarle un punto de partida sólido:
Nota : Incluí las ediciones proporcionadas por Confluence continuación, haciendo que el procedimiento sea un poco más conciso.
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});
}
Nota : hay un pequeño porcentaje de error al verificar los VIN debido a la naturaleza de la suma de comprobación:
... una coincidencia no prueba que el VIN sea correcto, porque todavía hay una posibilidad de 1 en 11 de que dos VIN distintos tengan un dígito de control coincidente.
También tenga en cuenta : 11111111111111111
se validará según el procedimiento anterior. Si desea o no comprobar que depende de usted:
Las rectas (diecisiete consecutivas ''1'') serán suficientes para el dígito de control. Esto se debe a que un valor de uno, multiplicado por 89 (suma de pesos), sigue siendo 89. Y 89% 11 es 1, el dígito de control. Esta es una manera fácil de probar un algoritmo de verificación de VIN.
referencia: en.wikipedia.org/wiki/…
Aquí hay una versión del código de jordan portada a Javascript, espero que sea útil para alguien ...
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));
}
Es "VIN". "Número VIN" = "Número de identificación del vehículo", que no tiene sentido.
Puedes ver una definición de la estructura de los VIN aquí:
http://en.wikipedia.org/wiki/Vehicle_identification_number
Y puedes trabajar desde allí, o puedes tomar este script aquí:
http://www.geekpedia.com/code29_Check-if-VIN-number-is-valid.html
Aquí hay una versión mejorada de la función publicada por 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});
}
Gracias a todos por el algoritmo, etc. que veo está en Wikipedia. Esta es la versión que armé basada en los comentarios anteriores. Tenga en cuenta que hay problemas con las versiones anteriores, por ejemplo, este 00000000000354888 devuelve OK para un vin. Tomé lo que estaba arriba y agregué una opción para verificar el año primero si es <1980, supongo que no es un vin real de 17 dígitos (tiene que hacerlo), y también si hay secuencias de un solo carácter, suponga que no es válido. Esto es lo suficientemente bueno para mis necesidades, ya que estoy comparando con valores que se llenan con 0 si no con 17 de longitud. También sé el valor del año, así que si compruebo que puedo acelerar el código saltándome el control de vin (sí, podría haberlo puesto antes de la función) 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);
}
}
PRUEBAS:
$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''));
Hace poco tuve que escribir una clase de validación VIN con PHP. Publiqué mi clase para que todos la usen en: http://dev.strategystar.net/2012/05/validate-vin-checksum-with-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.'');
}
}