Skip to content

Instantly share code, notes, and snippets.

@fionn
Last active May 10, 2020 07:51
Show Gist options
  • Save fionn/fb5b5d36bbec202781b91345aaea0e7c to your computer and use it in GitHub Desktop.
Save fionn/fb5b5d36bbec202781b91345aaea0e7c to your computer and use it in GitHub Desktop.
HKID Validator
#!/usr/bin/env python3
"""Calculate HKID check digit and validate HKID numbers"""
import sys
import operator
from typing import List
def _char_to_int(char: str) -> int:
"""Maps characters in ID to numeric value"""
try:
return int(char)
except ValueError:
if char == " ":
return 36
return ord(char) - 55
def _weighted_sum(id_list: List[int]) -> int:
weights = range(9, 1, -1)
return sum(map(operator.mul, id_list, weights))
def _prepare_id(id_str: str) -> str:
id_str = id_str.upper()
if ord(id_str[1]) < 58:
id_str = " " + id_str
return id_str
def _id_to_ints(id_str: str) -> List[int]:
output = []
for char in id_str:
output.append(_char_to_int(char))
return output
def _determine_check_digit(total: int) -> str:
modulus = total % 11
if modulus == 0:
return "0"
if modulus == 1:
return "A"
return str(11 - modulus)
def generate_check_digit(id_str: str) -> str:
"""Generat check digit from ID string"""
id_str = _prepare_id(id_str)
id_ints = _id_to_ints(id_str)
total = _weighted_sum(id_ints)
return _determine_check_digit(total)
def validate_id(id_str: str) -> bool:
"""Given ID and check digit, validate ID"""
id_str = id_str.replace("(", "").replace(")", "")
return str(id_str[-1]) == generate_check_digit(id_str[:-1])
def main() -> None:
"""Entry point"""
id_str = input()
if validate_id(id_str):
print("Valid", file=sys.stderr)
else:
print("Inalid", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment