#!/usr/bin/env python3 """Extract the IANA registered top-level-domain (TLD) list into tables. Source : https://data.iana.org/TLD/tlds-alpha-by-domain.txt Snapshot: Version 2026102600, Last Updated 2026-10-26 07:07:01 UTC Format : '# Version ...' comment header, then one lowercase TLD per line (1437 names, no blank lines, 9528 bytes). Outputs (same directory): tlds.csv per-TLD detail: tld,first_letter,length tlds_by_letter.tsv summary table: lettercount (no header) """ import hashlib import pathlib HERE = pathlib.Path(__file__).resolve().parent SRC = HERE / "tlds-alpha-by-domain.txt" MD5 = "8a32a215f1ad7eeb691d0731403b3208" def main(): data = SRC.read_bytes() actual = hashlib.md5(data).hexdigest() assert actual == MD5, f"source md5 mismatch: {actual} != {MD5}" rows = [ln.lower() for ln in data.decode("ascii").splitlines() if ln and not ln.startswith("#")] assert len(rows) == 1437, f"expected 1437 TLDs, got {len(rows)}" assert all(" " not in t for t in rows), "non-lower/space in names" with open(HERE / "tlds.csv", "w", encoding="ascii") as f: f.write("tld,first_letter,length\n") for t in rows: f.write(f"{t},{t[0]},{len(t)}\n") counts = {} for t in rows: counts[t[0]] = counts.get(t[0], 0) + 1 with open(HERE / "tlds_by_letter.tsv", "w", encoding="ascii") as f: for letter in sorted(counts): f.write(f"{letter}\t{counts[letter]}\n") print(f"MD5 ok | TLDs={len(rows)} | by-letter rows={len(counts)}") if __name__ == "__main__": main()