
de.kyrychenko.utils.vin.VinGeneratorUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vin-utils Show documentation
Show all versions of vin-utils Show documentation
Library for generate and validate vehicle identification number (VIN)
The newest version!
/*
* 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;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Random;
import java.util.stream.Stream;
/**
* Utility class providing help methods to generate vehicle identification number (VIN)
*/
public final class VinGeneratorUtils {
private static final Random RANDOM = new Random();
private static final String PREFIXES_FILE_NAME = "vin-prefixes.txt";
private static final String ALLOWED_CHARS = "0123456789ABCDEFGHJKLMNPRSTUVWXYZ";
private VinGeneratorUtils() {
throw new RuntimeException("Utility class should not be initialized");
}
/**
* Generate random VIN
*
* @return randomly generated VIN
*/
public static String getRandomVin() {
final Vin vinYear = getRandomVinStart();
final StringBuilder vinBuilder = new StringBuilder();
vinBuilder.append(vinYear.getWmi());
vinBuilder.append(vinYear.getVds());
vinBuilder.append(getRandomVinChar());
vinBuilder.append(vinYear.getYear());
for (int i = 0; i < 7; i++) {
vinBuilder.append(getRandomVinChar());
}
final String vin = vinBuilder.toString();
try {
final char checkSumChar = VinValidatorUtils.getVinCheckSumChar(vin);
return vin.substring(0, 8) + Character.toString(checkSumChar) + vin.substring(9);
} catch (InvalidVinException ignored) {
// should never happen, because here we calculate checksum for VIN generated by us
// but checksum calculation could throw exception for validation of foreign VIN
return null;
}
}
private static char getRandomVinChar() {
// '33' is length of ALLOWED_CHARS
return ALLOWED_CHARS.charAt(RANDOM.nextInt(33));
}
private static Vin getRandomVinStart() {
// '62178' is a number of lines in the file; + 1 to avoid reading of first line
final int lineToRead = RANDOM.nextInt(62177) + 1;
try (final Stream stream = Files.lines(Paths.get(ClassLoader.getSystemResource(PREFIXES_FILE_NAME).toURI()))) {
final String line = stream.skip(lineToRead)
.findFirst()
.orElseThrow(() -> new RuntimeException("Problem occurred while read line " + lineToRead + " from " + PREFIXES_FILE_NAME));
final String[] fields = line.split(" {3}");
return new Vin(fields[0].trim(), fields[1].trim(), fields[2].trim());
} catch (URISyntaxException | IOException | SecurityException e) {
throw new RuntimeException("Problem occurred while reading " + PREFIXES_FILE_NAME, e);
}
}
/**
* Helper class used internally to save parts of VIN
*/
private static class Vin {
/**
* WMI - (World Manufacturers Identification)
*/
private final String wmi;
/**
* VDS (Vehicle Description Section)
*/
private final String vds;
/**
* Year of model
*/
private final String year;
Vin(final String wmi,
final String vds,
final String year) {
this.wmi = wmi;
this.vds = vds;
this.year = year;
}
String getWmi() {
return this.wmi;
}
String getVds() {
return this.vds;
}
String getYear() {
return this.year;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy