Weboberflaeche: self-contained, client-side, CLI-kompatibel
Eine einzelne index.html ohne Framework/CDN. Krypto + LSB-Steganografie laufen komplett im Browser (iOS-tauglich). Format-identisch zum CLI; Byte-Interop in beide Richtungen per Node-Test gegen das Python-CLI abgesichert (laedt den Krypto-Kern direkt aus der ausgelieferten index.html). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
46
web/_interop_test.mjs
Normal file
46
web/_interop_test.mjs
Normal file
@@ -0,0 +1,46 @@
|
||||
// Interop-Test: lädt EXAKT den Core-Block aus der ausgelieferten index.html
|
||||
// und prüft Byte-Kompatibilität mit dem Python-CLI in beide Richtungen.
|
||||
import { readFileSync, writeFileSync } from "node:fs";
|
||||
|
||||
const html = readFileSync(new URL("./index.html", import.meta.url), "utf8");
|
||||
const core = html.match(/==CORE START==.*?\*\/([\s\S]*?)\/\*\s*==CORE END==/)[1];
|
||||
// Core in diesem Modul-Scope ausführen; er hängt SP an globalThis.
|
||||
new Function(core)();
|
||||
const SP = globalThis.SP;
|
||||
|
||||
let fails = 0;
|
||||
const ok = (c, m) => { console.log((c ? " ✓ " : " ✗ ") + m); if (!c) fails++; };
|
||||
|
||||
// ---------- A: CLI -> Web (mit dem CLI erzeugtes Bild im Browser-Core aufdecken)
|
||||
{
|
||||
const dims = readFileSync(new URL("./_a_dims.txt", import.meta.url), "utf8").trim();
|
||||
const rgb = new Uint8Array(readFileSync(new URL("./_a_rgb.bin", import.meta.url)));
|
||||
const pad = new Uint8Array(readFileSync(new URL("../pad.key", import.meta.url)));
|
||||
const expected = "Treffpunkt morgen 18 Uhr am alten Hafen. Bring das Buch mit. 🕵️";
|
||||
|
||||
const { offset, ciphertext } = SP.extract(rgb);
|
||||
const plain = SP.otpXor(ciphertext, pad, offset);
|
||||
const text = new TextDecoder().decode(plain);
|
||||
console.log("A) CLI → Web (dims " + dims + ")");
|
||||
ok(offset === 0, "Offset aus Bild gelesen = 0");
|
||||
ok(text === expected, "Klartext stimmt: " + JSON.stringify(text));
|
||||
}
|
||||
|
||||
// ---------- B: Web -> CLI (im Browser-Core einbetten, vom CLI aufdecken lassen)
|
||||
{
|
||||
const [w, h] = readFileSync(new URL("./_b_dims.txt", import.meta.url), "utf8").trim().split(" ").map(Number);
|
||||
const rgb = new Uint8Array(readFileSync(new URL("./_b_rgb.bin", import.meta.url)));
|
||||
const pad = new Uint8Array(readFileSync(new URL("../pad.key", import.meta.url)));
|
||||
const msg = "Nachricht direkt aus dem Browser-Core 🌐 — Interop!";
|
||||
const offset = 500; // frischer Pad-Bereich
|
||||
|
||||
const plain = new TextEncoder().encode(msg);
|
||||
const ct = SP.otpXor(plain, pad, offset);
|
||||
const payload = SP.buildPayload(offset, ct);
|
||||
SP.embed(rgb, payload);
|
||||
writeFileSync(new URL("./_b_out_rgb.bin", import.meta.url), rgb);
|
||||
console.log("B) Web → CLI");
|
||||
ok(true, `eingebettet (${plain.length} B ab Offset ${offset}) → _b_out_rgb.bin (${w}x${h})`);
|
||||
}
|
||||
|
||||
process.exit(fails ? 1 : 0);
|
||||
Reference in New Issue
Block a user