jupyter/validate.ipynb
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "initial_id",
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import os\n",
"from datetime import datetime\n",
"\n",
"\n",
"class Validate:\n",
" @staticmethod\n",
" def this_email(email_address: str) -> bool:\n",
" if (1 <= len(email_address) <= 320) and \" \" not in email_address and \"@\" in email_address:\n",
" local_part, domain_part = email_address.rsplit(\"@\", 1)\n",
" if local_part and domain_part and \".\" in domain_part:\n",
" domain_labels = domain_part.split(\".\")\n",
" if all(label.isalnum() for label in domain_labels) and 2 <= len(domain_labels[-1]) <= 63:\n",
" return True\n",
" return False\n",
"\n",
" @staticmethod\n",
" def _url_by_parsing(url: str) -> dict | bool:\n",
" if not url:\n",
" return False\n",
" # Read TLDs from file\n",
" record_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'registered.tld.record')\n",
" with open(record_path, 'r') as file:\n",
" tlds = {line.strip().lower() for line in file.readlines()[1:]}\n",
"\n",
" # Split the URL into components\n",
" if '://' not in url:\n",
" return False\n",
"\n",
" protocol, rest = url.split('://', 1)\n",
" if '/' in rest:\n",
" hostname, filename = rest.split('/', 1)\n",
" filename = '/' + filename\n",
" else:\n",
" hostname = rest\n",
" filename = ''\n",
"\n",
" # Extract TLD from hostname\n",
" tld = hostname.split('.')[-1].lower()\n",
" is_registered_tld = tld in tlds\n",
"\n",
" if not hostname.startswith('www.'):\n",
" hostname = 'www.' + hostname\n",
"\n",
" return {\n",
" 'protocol': protocol,\n",
" 'hostname': hostname,\n",
" 'filename': filename,\n",
" 'TLD': is_registered_tld\n",
" }\n",
"\n",
" @classmethod\n",
" def this_url(cls, url: str, text_error: bool = False,\n",
" enforce_https: bool = False) -> bool:\n",
" parsed_url = cls._url_by_parsing(url)\n",
" if not parsed_url:\n",
" return cls.__return_error('Invalid URL: Reason - URL is empty or does not contain a protocol', text_error)\n",
"\n",
" if not cls.__validate_protocol(parsed_url['protocol'], enforce_https, text_error):\n",
" return False\n",
"\n",
" if not cls.__validate_hostname(parsed_url['hostname'], text_error):\n",
" return False\n",
"\n",
" if not cls.__validate_filename(parsed_url['filename'], text_error):\n",
" return False\n",
"\n",
" if not parsed_url['TLD']:\n",
" return cls.__return_error('Invalid URL: Reason - TLD is not registered', text_error)\n",
"\n",
" return True\n",
"\n",
" @staticmethod\n",
" def __return_error(message: str, text_error: bool) -> bool:\n",
" return message if text_error else False\n",
"\n",
" @classmethod\n",
" def __validate_protocol(cls, protocol: str, enforce_https: bool, text_error: bool) -> bool:\n",
" if protocol not in ['http', 'https']:\n",
" return cls.__return_error('Invalid URL: Reason - Protocol is not HTTP or HTTPS', text_error)\n",
" if enforce_https and protocol != 'https':\n",
" return cls.__return_error('Invalid URL: Reason - HTTPS protocol is enforced', text_error)\n",
" return True\n",
"\n",
" @classmethod\n",
" def __validate_hostname(cls, hostname: str, text_error: bool) -> bool:\n",
" if len(hostname) > 253:\n",
" return cls.__return_error('Invalid URL: Reason - Hostname is too long', text_error)\n",
" if hostname.count('.') < 1:\n",
" return cls.__return_error('Invalid URL: Reason - Hostname does not contain a domain', text_error)\n",
" hostname_labels = hostname.split('.')\n",
" for label in hostname_labels:\n",
" if not all(c.isalnum() or c == '-' for c in label):\n",
" return cls.__return_error('Invalid URL: Reason - Invalid character in hostname', text_error)\n",
" if label.startswith('-') or label.endswith('-'):\n",
" return cls.__return_error('Invalid URL: Reason - Label starts or ends with a hyphen', text_error)\n",
" if label.isdigit():\n",
" return cls.__return_error('Invalid URL: Reason - Label is a number', text_error)\n",
" return True\n",
"\n",
" @classmethod\n",
" def __validate_filename(cls, filename: str, text_error: bool) -> bool:\n",
" if len(filename) > 256:\n",
" return cls.__return_error('Invalid URL: Reason - Filename is too long', text_error)\n",
" if ' ' in filename:\n",
" return cls.__return_error('Invalid URL: Reason - Filename contains spaces', text_error)\n",
" return True\n",
"\n",
" @staticmethod\n",
" def this_phone_number(phone_number: int | str) -> bool:\n",
" \"\"\"\n",
" Validates a phone number against a set of predefined formats.\n",
" Allow only digits, parentheses, hyphens, periods, and spaces.\n",
"\n",
" Allowed formats:\n",
" \"(###)###-####\",\n",
" \"(###)-###-####\",\n",
" \"(###)###-###-####\",\n",
" \"(###)-###-###-####\",\n",
" \"(###)###-####-###\",\n",
" \"(###)-###-####-###\",\n",
" \"###-###-####\",\n",
" \"###-####-###\",\n",
" \"##########\",\n",
" Where # is a digit and - is a separator of any type allowed.\n",
"\n",
" Args:\n",
" phone_number (int | str): The phone number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the phone number is valid, False otherwise.\n",
" \"\"\"\n",
" phone_number = str(phone_number)\n",
" allowed_chars = set(\"0123456789()+-. \")\n",
" if not all(char in allowed_chars for char in phone_number):\n",
" return False\n",
"\n",
" phone_number_list = list(phone_number)\n",
" for i, char in enumerate(phone_number_list):\n",
" if char.isdigit():\n",
" phone_number_list[i] = '#'\n",
" elif char == '+' or char == '.' or char == ' ':\n",
" phone_number_list[i] = '-'\n",
"\n",
" formatted_phone_number = ''.join(phone_number_list)\n",
" valid_formats = [\n",
" \"(###)###-####\",\n",
" \"(###)-###-####\",\n",
" \"(###)###-###-####\",\n",
" \"(###)-###-###-####\",\n",
" \"(###)###-####-###\",\n",
" \"(###)-###-####-###\",\n",
" \"###-###-####\",\n",
" \"###-####-###\",\n",
" \"##########\",\n",
" ]\n",
"\n",
" return formatted_phone_number in valid_formats\n",
"\n",
" @staticmethod\n",
" def this_date(date: str, datetime_format: str = \"%Y-%m-%d\") -> bool:\n",
" r\"\"\"\n",
" Validates a date string.\n",
"\n",
" The allowed date formats in the selected code are:\n",
"\n",
" - `DD-MM-YYYY`\n",
" - `YYYY-MM-DD`\n",
"\n",
" These formats are normalized to either `YYYY-MM-DD` or `DD-MM-YYYY` before validation.\n",
" Where `-` is a separator, and can be from the following set [-, /, \\, ].\n",
"\n",
" Args:\n",
" date (str): The date string to be validated.\n",
" datetime_format (str): The format of the date string. Defaults to `\"%Y-%m-%d\"`. Always falls-back to `\"%d-%m-%Y\"`.\n",
"\n",
" Returns:\n",
" bool: True if the date string is valid, False otherwise.\n",
" \"\"\"\n",
" if not date:\n",
" return False\n",
" date = date.replace(\"/\", \"-\")\n",
" date = date.replace(\"\\\\\", \"-\")\n",
" date = date.replace(\" \", \"-\")\n",
" try:\n",
" datetime.strptime(date, datetime_format)\n",
" return True\n",
" except ValueError:\n",
" try:\n",
" datetime.strptime(date, \"%d-%m-%Y\")\n",
" return True\n",
" except ValueError:\n",
" return False\n",
"\n",
" class CreditCard:\n",
" def __init__(self):\n",
" \"\"\"\n",
" Validates a card number using the Luhn algorithm.\n",
" Specify in specifics inside the class.\n",
"\n",
" Returns a boolean value if the card number is valid or not.\n",
" \"\"\"\n",
" pass\n",
"\n",
" @classmethod\n",
" def __luhn_algorithm(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates a card number using the Luhn algorithm.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" if len(card_number) < 13 or len(card_number) > 19:\n",
" return False\n",
"\n",
" num_list = [int(digit) for digit in card_number]\n",
" num_list.reverse()\n",
"\n",
" total = sum(cls.__luhn_double(num) if i % 2 == 1 else num for i, num in enumerate(num_list))\n",
" return total % 10 == 0\n",
"\n",
" @staticmethod\n",
" def __luhn_double(num: int) -> int:\n",
" \"\"\"\n",
" Doubles the number and subtracts 9 if the result is greater than 9.\n",
"\n",
" Args:\n",
" num (int): The number to be doubled.\n",
"\n",
" Returns:\n",
" int: The processed number.\n",
" \"\"\"\n",
" doubled = num * 2\n",
" return doubled - 9 if doubled > 9 else doubled\n",
"\n",
" @classmethod\n",
" def american_express(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates American Express card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return cls.__luhn_algorithm(card_number) and (\n",
" str(card_number).startswith((\"34\", \"37\"))\n",
" and 15 <= len(str(card_number)) <= 16\n",
" )\n",
"\n",
" @classmethod\n",
" def china_unionpay(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates China UnionPay card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return cls.__luhn_algorithm(card_number) and (\n",
" str(card_number).startswith(\n",
" (\n",
" \"62\",\n",
" \"64\",\n",
" \"65\",\n",
" \"66\",\n",
" \"67\",\n",
" \"68\",\n",
" \"69\",\n",
" \"92\",\n",
" \"93\",\n",
" \"94\",\n",
" \"95\",\n",
" \"96\",\n",
" \"97\",\n",
" \"98\",\n",
" \"99\",\n",
" )\n",
" )\n",
" and 16 <= len(str(card_number))\n",
" )\n",
"\n",
" @classmethod\n",
" def dankort(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates Dankort card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return (\n",
" cls.__luhn_algorithm(card_number)\n",
" and str(card_number).startswith(\"49\")\n",
" and 16 <= len(str(card_number))\n",
" )\n",
"\n",
" @classmethod\n",
" def diners_club(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates Diners Club International card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return cls.__luhn_algorithm(card_number) and (\n",
" str(card_number).startswith((\"36\", \"38\"))\n",
" and 14 <= len(str(card_number)) <= 19\n",
" )\n",
"\n",
" @classmethod\n",
" def discover(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates Discover card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return cls.__luhn_algorithm(card_number) and (\n",
" str(card_number).startswith(\n",
" (\n",
" \"6011\",\n",
" \"6221\",\n",
" \"6222\",\n",
" \"6223\",\n",
" \"623\",\n",
" \"624\",\n",
" \"625\",\n",
" \"626\",\n",
" \"627\",\n",
" \"628\",\n",
" \"641\",\n",
" \"642\",\n",
" \"643\",\n",
" \"644\",\n",
" \"645\",\n",
" \"646\",\n",
" \"647\",\n",
" \"648\",\n",
" \"649\",\n",
" \"65\",\n",
" \"66\",\n",
" \"67\",\n",
" \"68\",\n",
" \"69\",\n",
" \"71\",\n",
" \"72\",\n",
" \"73\",\n",
" \"74\",\n",
" \"75\",\n",
" \"76\",\n",
" \"77\",\n",
" \"78\",\n",
" \"79\",\n",
" )\n",
" )\n",
" and 16 <= len(str(card_number))\n",
" )\n",
"\n",
" @classmethod\n",
" def jcb(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates JCB card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return (\n",
" cls.__luhn_algorithm(card_number)\n",
" and str(card_number).startswith(\"35\")\n",
" and 16 <= len(str(card_number))\n",
" )\n",
"\n",
" @classmethod\n",
" def maestro(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates Maestro card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return cls.__luhn_algorithm(card_number) and (\n",
" str(card_number).startswith(\n",
" (\n",
" \"50\",\n",
" \"51\",\n",
" \"52\",\n",
" \"53\",\n",
" \"54\",\n",
" \"55\",\n",
" \"56\",\n",
" \"57\",\n",
" \"58\",\n",
" \"60\",\n",
" \"61\",\n",
" \"62\",\n",
" \"63\",\n",
" \"64\",\n",
" \"65\",\n",
" \"66\",\n",
" \"67\",\n",
" \"68\",\n",
" \"69\",\n",
" \"70\",\n",
" \"71\",\n",
" \"72\",\n",
" \"73\",\n",
" \"74\",\n",
" \"75\",\n",
" \"76\",\n",
" \"77\",\n",
" \"78\",\n",
" \"79\",\n",
" )\n",
" )\n",
" and 12 <= len(str(card_number)) <= 19\n",
" )\n",
"\n",
" @classmethod\n",
" def mastercard(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates Mastercard card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return (\n",
" cls.__luhn_algorithm(card_number)\n",
" and str(card_number).startswith((\"51\", \"52\", \"53\", \"54\", \"55\", \"56\", \"57\", \"58\", \"59\"))\n",
" and 16 <= len(str(card_number))\n",
" )\n",
"\n",
" @classmethod\n",
" def visa(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates Visa card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return (\n",
" cls.__luhn_algorithm(card_number)\n",
" and str(card_number).startswith(\"4\")\n",
" and 13 <= len(str(card_number)) <= 16\n",
" )\n",
"\n",
" @classmethod\n",
" def visa_electron(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates Visa Electron card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return (\n",
" cls.__luhn_algorithm(card_number)\n",
" and str(card_number).startswith((\"40\", \"41\", \"42\", \"43\", \"44\", \"45\", \"46\", \"47\", \"48\", \"49\"))\n",
" and 16 <= len(str(card_number))\n",
" )\n",
"\n",
" @classmethod\n",
" def v_pay(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates V Pay card numbers.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return (\n",
" cls.__luhn_algorithm(card_number)\n",
" and str(str(card_number)).startswith(\"28\")\n",
" and 16 <= len(str(str(card_number)))\n",
" )\n",
"\n",
" @classmethod\n",
" def any(cls, card_number: str) -> bool:\n",
" \"\"\"\n",
" Validates any card number just by passing it to the Luhn algorithm.\n",
"\n",
" Args:\n",
" card_number (str): The card number to be validated.\n",
"\n",
" Returns:\n",
" bool: True if the card number is valid, False otherwise.\n",
" \"\"\"\n",
" return cls.__luhn_algorithm(card_number)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}