All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.kyrychenko.utils.vin.VinValidatorUtils Maven / Gradle / Ivy

/*
 * MIT License
 *
 * Copyright (c) 2018 Mykhailo Kyrychenko 
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package de.kyrychenko.utils.vin;

/**
 * Utility class providing help methods to validate vehicle identification number (VIN)
 * 

* Based on script placed in GitHub * VinGenerator project
* and partly improved with algorithm of * princeton university */ public final class VinValidatorUtils { private static final int[] VIN_POSITION_WEIGHT = {8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2}; private static final int[] VIN_LETTER_VALUE = {1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 0, 7, 0, 9, 2, 3, 4, 5, 6, 7, 8, 9}; private VinValidatorUtils() { throw new RuntimeException("Utility class should not be initialized"); } /** * Check whether provided VIN is a valid one, * suppressing all errors in case of wrong vin. * * @param vin a string to validate * @return {@code true} if specified parameter is a valid VIN, {@code false} otherwise */ public static boolean isValidVin(final String vin) { try { return validateVin(vin); } catch (InvalidVinException e) { return false; } } /** * Validate vehicle identification number (VIN) * * @param vin a {@link String} with VIN to validate * @return {@code true} if specified parameter is a valid VIN, {@code false} otherwise * @throws InvalidVinException if validation was failed */ public static boolean validateVin(final String vin) throws InvalidVinException { final String normalized = normalizeVin(vin); final int sum = getVinCheckSum(normalized); final char check = normalized.charAt(8); if (check != 'X' && (check < '0' || check > '9')) { throw new InvalidVinException(normalized, "Illegal check digit '" + check + "' for VIN '" + normalized + "'"); } return (sum == 10 && check == 'X') || (sum == check - '0'); } /** * Calculate VIN checksum * * @param vin a {@link String} with VIN to checksum for * @return checksum of VIN * @throws InvalidVinException if calculation was failed */ public static int getVinCheckSum(final String vin) throws InvalidVinException { final String normalized = normalizeVin(vin); int sum = 0; for (int i = 0; i < 17; i++) { final char key = normalized.charAt(i); int value = 0; if (key >= 'A' && key <= 'Z') { value = VIN_LETTER_VALUE[key - 'A']; if (value == 0) { throw new InvalidVinException(normalized, String.format("Illegal character '%s' in VIN '%s' at position %d", key, normalized, i)); } } else if (key >= '0' && key <= '9') { value = Character.getNumericValue(key); } else { throw new InvalidVinException(normalized, String.format("Illegal character '%s' in VIN '%s' at position %d", key, normalized, i)); } sum += value * VIN_POSITION_WEIGHT[i]; } return sum % 11; } /** * Calculate VIN checksum char * * @param vin a VIN to get the checksum for * @return checksum for provided VIN * @throws InvalidVinException if checksum calculation was failed */ public static char getVinCheckSumChar(final String vin) throws InvalidVinException { final int checkSum = VinValidatorUtils.getVinCheckSum(vin); if (checkSum == 10) { return 'X'; } else { return (char) (checkSum + '0'); } } private static String normalizeVin(final String vin) throws InvalidVinException { if (vin == null) { throw new InvalidVinException(null, "VIN should not be null"); } final String normalized = vin.toUpperCase().replaceAll("[^A-Z0-9]", ""); if (normalized.length() != 17) { throw new InvalidVinException(normalized, "Length of VIN (without possible additional characters) should equal 17"); } return normalized; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy