"""Kompatibilitaetstest Python <-> Kotlin (Android). python tools/interop.py gen /tmp/interop (cd client-android && ./gradlew testDebugUnitTest -Pinterop=/tmp/interop) python tools/interop.py check /tmp/interop """ import hashlib import io import json import os import sys import zipfile from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "client-desktop")) from netclip.crypto import Keys # noqa: E402 TOKEN = "Interop-Tökén-123" def gen(d: Path): d.mkdir(parents=True, exist_ok=True) k = Keys(TOKEN) data = os.urandom(2 * 1024 * 1024 + 123) (d / "plain.bin").write_bytes(data) with open(d / "from_python.enc", "wb") as f: k.encrypt_stream(io.BytesIO(data), f) with zipfile.ZipFile(d / "from_python.zip", "w") as z: z.writestr("Ordner/", "") z.writestr("Ordner/sub/datei.txt", "inhalt") z.writestr("../boese.txt", "x") (d / "vectors.json").write_text(json.dumps({ "token": TOKEN, "room_id": k.room_id, "meta": k.encrypt_meta({"preview": "Grüße aus Python"}), "sha256": hashlib.sha256(data).hexdigest()})) print("Testdaten in", d) def check(d: Path): k = Keys(TOKEN) assert k.decrypt_meta((d / "from_kotlin.meta").read_text())["preview"] == "Hallo von Kotlin äöü" out = io.BytesIO() with open(d / "from_kotlin.enc", "rb") as f: k.decrypt_stream(f, out) assert out.getvalue() == (d / "plain.bin").read_bytes() assert not (d / "boese.txt").exists() and not (d.parent / "boese.txt").exists() print("OK: Kotlin -> Python kompatibel") if __name__ == "__main__": {"gen": gen, "check": check}[sys.argv[1]](Path(sys.argv[2]))