Skip to content

Instantly share code, notes, and snippets.

@mattgen88
Created November 18, 2019 20:41
Show Gist options
  • Save mattgen88/305abe79c8ae732e3bb3de558553c5fe to your computer and use it in GitHub Desktop.
Save mattgen88/305abe79c8ae732e3bb3de558553c5fe to your computer and use it in GitHub Desktop.
Fun with learning about VINs
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