Last active
July 10, 2023 09:37
-
-
Save errkk/1764d49a71206e1d7416777f345b72a6 to your computer and use it in GitHub Desktop.
Generate Driving licence number
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
#! /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