Search code examples
validationcoldfusionvin

ColdFusion VIN number validation code


I am trying to convert this PHP validation code to ColdFusion. However, I cannot get my CF version to correctly validate a VIN. I am hoping someone can shed some light on what I'm 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})[A-Z]{2}\d{2}([A-Z]{1}|\d{1})([\d{1}|X{1})([A-Z]+\d+|\d+[A-Z]+)\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>

(There is a VIN validation function at CFLib.org, but it doesn't work either).


Solution

  • Your function has two issues.

    First, the regex is incorrect. Here's a simplified working version:

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

    Note: As per Adam's answer there's a simpler pattern than this.


    Second, in your checkdigit comparison the Mid is one out - it seems the 8 should be a 9.

    (Presumably this is a language conversion issue due to PHP being 0-indexed whilst CFML is 1-indexed.)


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