-
-
Save mattgen88/305abe79c8ae732e3bb3de558553c5fe to your computer and use it in GitHub Desktop.
Fun with learning about VINs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
transliteration_table = { | |
"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, | |
"1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, | |
"0": 0, | |
} | |
weights_table = [8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2] | |
def check_sum(vin: str): | |
vin = vin.upper() | |
# Check length of VIN | |
if len(vin) != 17: | |
print(f"error: VINs are 17 chars: {vin}") | |
return False | |
# Check for invalid characters in VIN | |
if "I" in vin or "O" in vin or "Q" in vin: | |
print(f"error: VINs do not contain I, O, or Q") | |
return False | |
check_value = vin[8] # Calculated checksum should match this value | |
products = [] | |
pos = 0 | |
# Multiply each transliterated VIN char by position weight | |
for char in vin: | |
char_value = transliteration_table[char] | |
weight_value = weights_table[pos] | |
products.append(char_value * weight_value) | |
pos += 1 | |
# sum mod 11 gives VIN checksum, if 10, char should be X | |
sum_value = sum(products) % 11 | |
if sum_value == 10: | |
return check_value == "X" | |
if transliteration_table[check_value] != sum_value: | |
print(f"VIN: {vin} failed check sum, expected {sum_value} but found {check_value}") | |
return True | |
#True == check_sum("VF1LM1B0H36666155") | |
#False == check_sum("") | |
#False == check_sum("111111111111111111") | |
#True == check_sum("11111111111111111") | |
#True == check_sum("1M8GDM9AXKP042788") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment