Logo Lanfrica

endafk/msisdn-lookup

Domaine:

digital infrastructure

Type de record:

software
Créateur:
end
Hôte:
Recover phone numbers from hashed MPesa Daraja callbacks. <1ms lookups, pure Python stdlib. # MSISDN Binary Search Hash Lookup Reverse-lookup SHA256 hashes of Kenyan phone numbers from MPesa Daraja API callbacks. Sub-millisecond lookups against a 2.8 GB sorted binary file. Pure Python stdlib for the core; `boto3` only if you want S3 upload or Lambda. --- ## The problem Safaricom's MPesa Daraja API used to include the subscriber's phone number in plain text (partially masked) in payment callbacks — for example, in C2B Pay Bill callbacks: ```json { "TransactionType": "Pay Bill", "TransID": "RKL51ZDR4F", "TransTime": "20231121121325", "TransAmount": "5.00", "BusinessShortCode": "600966", "BillRefNumber": "Sample Transaction", "InvoiceNumber": "", "OrgAccountBalance": "25.00", "ThirdPartyTransID": "", "MSISDN": "fc418dcfe94c732a...", // ← SHA256 hash of the phone number (used to be plaintext e.g. "2547 ***** 126") "FirstName": "NICHOLAS", "MiddleName": "", "LastName": "" } ``` SHA256 is a one-way function — you cannot mathematically reverse it. The only way to recover the original phone number is to hash every possible candidate and check for a match. For Kenyan Safaricom numbers this means checking up to 200 million candidates (`2547XXXXXXXX` and `2541XXXXXXXX`). Doing that on every callback request is not viable. --- ## Why not other approaches | Approach | Lookup time | Notes | |---|---|---| | Brute-force per request | ~2 min | Hashes 200M numbers on every lookup. Completely unusable in practice. | | Store hashes in a database (SQLite, Postgres) | ~5–50 ms | Requires a DB server or large SQLite file (~15 GB with indexes), plus query overhead. | | Rainbow tables | Saves some space | Complex to implement correctly, slower than direct lookup, and the search space here is small enough not to need them. | | **Sorted binary file + binary search** | ** **Note on file size.** Each record stores the first 10 bytes (80 bits) of the SHA-256 plus a 4-byte index, for 14 bytes per record. Birthday-collision probability across all 200M MSISDNs is ~1.6 × …