VIN Verification Code for ColdFusion

I am trying to convert this PHP validation code to ColdFusion. However, I cannot get the CF version to validate the VIN correctly. I hope someone can shed light on what I am missing.

<cfscript> function isVIN(v) { var i = ""; var d = ""; var checkdigit = ""; var sum = 0; var weights = [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 }; if (! REFindNoCase("^([\w]{3})[AZ]{2}\d{2}([AZ]{1}|\d{1})([\d{1}|X{1})([AZ]+\d+|\d+[AZ]+)\d{5}$", ARGUMENTS.v)) { return false; } if (Len(ARGUMENTS.v) != 17) { return false; } for (i = 1; i <= Len(ARGUMENTS.v); i++) { d = Mid(ARGUMENTS.v, i, 1); if (! isNumeric(d)) { sum += transliterations[d] * weights[i]; } else { sum += d * weights[i]; } } checkdigit = sum % 11; if (checkdigit == 10) { checkdigit = "x"; } if (checkdigit == Mid(ARGUMENTS.v,8,1)) { return true; } return false; } </cfscript> 

(CFLib.org has a VIN check function, but it does not work.)

+4
source share
2 answers

Your function has two problems.

Firstly, the regular expression is incorrect. Here is a simplified working version:

 ^[AZ\d]{3}[AZ]{2}\d{2}[AZ\d][\dX](?:[AZ]+\d+|\d+[AZ]+)\d{5}$ 

Note. . According to Adam , there is a simpler template.


Secondly, in your Mid benchmark - one - it seems like 8 should be 9.

(Presumably, this is a language conversion problem due to the fact that PHP is 0-indexed and CFML is 1-indexed.)


With both of these fixes, the modified function returns true for VIN WAUBA24B3XN104537 (which is the only VIN sample that I could find as a result of a quick search).

+8
source

Actually the regex is still a bit wrong. I think @PeterBoughton corrected the syntax, but in reality it was not valid for this task.

Here's a revised code section with relevant comments:

 var vinRegex = "(?x) ## allow comments ^ ## from the start of the string ## see http://en.wikipedia.org/wiki/Vehicle_Identification_Number for VIN spec [AZ\d]{3} ## World Manufacturer Identifier (WMI) [AZ\d]{5} ## Vehicle decription section (VDS) [\dX] ## Check digit [AZ\d] ## Model year [AZ\d] ## Plant \d{6} ## Sequence $ ## to the end of the string "; if (! REFindNoCase(vinRegex, arguments.v)) { return false; } 

This can be greatly simplified to this:

 ^[AZ\d]{8}[\dX][AZ\d]{2}\d{6}$ 

Using either of these also obviates the requirement of checking length, since the regular expression will also force this.

Test code for this modification:

 for (vin in [ "1GNDM19ZXRB170064", "1FAFP40634F172825" ]){ writeOutput("#vin#: #isVin(vin)#<br />"); } 

I am going to update CFLib with a detailed version, as it is easier to understand what is happening and marry the specification.

+3
source

All Articles