fix(qr): Use hybrid Chunked+Qt format for QR codes

The format that likely works with Amnezia Android is:
HEADER: 0x07C00100 (Magic 1984, Count 1, Id 0)
PAYLOAD: [UncompressedLen (4b)] + [Zlib Data]

This satisfies the Chunked QR check (magic 0x07C0) and then passes
the payload to qUncompress, which expects the 4-byte uncompressed length prefix.

Previous attempts failed because:
1. 12-byte header included compressedLen, which qUncompress interpreted as uncompressedLen (causing size mismatch error)
2. 4-byte header (Qt only) failed the Magic check
This commit is contained in:
infosave2007
2026-01-24 13:38:32 +03:00
parent 00affda8f2
commit 939cba70b7
+4 -5
View File
@@ -63,16 +63,15 @@ class QrUtil
public static function encodeOldPayloadFromJson(string $jsonText): string public static function encodeOldPayloadFromJson(string $jsonText): string
{ {
$json = self::normalizeJson($jsonText); $json = self::normalizeJson($jsonText);
// Amnezia format: 12-byte header [version, compressed_len, uncompressed_len] + zlib compressed data
// Version 0x07C00100 is required for compatibility with Amnezia apps
$compressed = gzcompress($json, 9); $compressed = gzcompress($json, 9);
if ($compressed === false) { if ($compressed === false) {
throw new RuntimeException('gzcompress failed'); throw new RuntimeException('gzcompress failed');
} }
$uncompressedLen = strlen($json); $uncompressedLen = strlen($json);
$compressedLen = strlen($compressed) + 4; // +4 for the uncompressed length field $version = 0x07C00100; // Magic 1984 (07C0), Count 1, Id 0
$version = 0x07C00100; // Amnezia magic version number // Pack version (4 bytes) and uncompressed length (4 bytes)
$header = pack('N3', $version, $compressedLen, $uncompressedLen); // Note: we skipped compressedLen which was present in old format but invalid for qUncompress
$header = pack('NN', $version, $uncompressedLen);
return self::urlsafe_b64_encode($header . $compressed); return self::urlsafe_b64_encode($header . $compressed);
} }