Skip to content

Instantly share code, notes, and snippets.

@errkk
Last active July 10, 2023 09:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save errkk/1764d49a71206e1d7416777f345b72a6 to your computer and use it in GitHub Desktop.
Save errkk/1764d49a71206e1d7416777f345b72a6 to your computer and use it in GitHub Desktop.
Generate Driving licence number
#! /usr/bin/python3
# Thing for making up a valid (ish) driving licence number
# https://www.drivercheck.co.uk/find-out-more/photocard-driving-licence-explained/
# Note checksum is just dumped on there, not generated cos IDK how it's calculated
import argparse
from datetime import date
from typing import Tuple
def parse_date(date_str: str) -> date:
try:
return date.fromisoformat(date_str)
except ValueError:
raise argparse.ArgumentTypeError("Invalid date format. Please use YYYY-MM-DD.")
def parse_name(name_str: str) -> Tuple[str, str, str | None]:
match name_str.split(" "):
case (str(first_name), str(last_name)):
return first_name.upper(), last_name.upper(), None
case (str(first_name), str(middle_name), str(last_name)):
return first_name.upper(), last_name.upper(), middle_name.upper()
case _:
raise argparse.ArgumentTypeError(
'Invalid name. Please use "first_name middle_name last name."'
)
def main():
parser = argparse.ArgumentParser(description="Driving licence number generator")
parser.add_argument("date", type=parse_date, help="Date in the format YYYY-MM-DD")
parser.add_argument("name", type=parse_name, help="Firstname Lastname")
parser.add_argument(
"-g",
"--gender",
choices=["f", "m", "🤷‍♂️"],
default="🤷‍♂️",
required=False,
)
args = parser.parse_args()
parts = []
first_name, last_name, middle_name = args.name
# Driver number (5): Driving licence number format explained.
# JONES – Displaying the first five letters of your surname. If a surname is less than five characters in length, the remaining spaces will comprise of the digit 9.
parts.append(last_name[:5].ljust(5, "9"))
# 849339 – First and last numbers are the year of birth.
parts.append(args.date.strftime("%Y")[2])
# The second and third numbers are the month of birth.
# (Note: in the case of female driving licence holders, ‘5’ is added to the second digit, this means that the second digit will be 5 or 6).
if args.gender == "f":
parts.append(str(int(args.date.strftime("%m")) + 50))
else:
parts.append(args.date.strftime("%m"))
# The fourth and fifth digits are the day of the month of your birth.
parts.append(args.date.strftime("%d"))
# Last number of year
parts.append(args.date.strftime("%Y")[3])
# TS – The first two initials of your forenames.
parts.append(first_name[:1])
# If you have only one initial then the second character will be a ‘9’.
parts.append(middle_name[:1] or "9")
# 9AD – Computer check digits.
parts.append("9AD")
print("".join(parts))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment