A Python port of the Invisible Internet Project (I2P)
at main 46 lines 1.4 kB view raw
1"""Convert various I2P address formats to a 32-byte hash. 2 3Ported from net.i2p.util.ConvertToHash. 4""" 5 6from __future__ import annotations 7 8import base64 9 10 11def convert_to_hash(input_str: str) -> bytes | None: 12 """Convert a Base64 hash, .b32.i2p address, or full destination to a 32-byte hash. 13 14 Returns None if the input is not a recognized format. 15 """ 16 if not input_str: 17 return None 18 19 # 43 or 44-char Base64 → raw 32-byte hash 20 # I2P uses modified Base64: -~ instead of +/ 21 # 32 bytes = 43 Base64 chars + 1 padding, or 44 chars if padding included 22 if len(input_str) in (43, 44) and not input_str.endswith(".i2p"): 23 try: 24 std = input_str.replace("-", "+").replace("~", "/") 25 # Pad to multiple of 4 26 pad = (4 - len(std) % 4) % 4 27 decoded = base64.b64decode(std + "=" * pad) 28 if len(decoded) == 32: 29 return decoded 30 except Exception: 31 pass 32 return None 33 34 # 52-char-prefix.b32.i2p → Base32 decode to 32 bytes 35 if input_str.endswith(".b32.i2p"): 36 b32_part = input_str[: -len(".b32.i2p")] 37 if len(b32_part) == 52: 38 try: 39 decoded = base64.b32decode(b32_part.upper() + "====") 40 if len(decoded) == 32: 41 return decoded 42 except Exception: 43 pass 44 return None 45 46 return None