Remove WireGuard integration from production deployment to simplify infrastructure: - Remove docker-compose-direct-access.yml (VPN-bound services) - Remove VPN-only middlewares from Grafana, Prometheus, Portainer - Remove WireGuard middleware definitions from Traefik - Remove WireGuard IPs (10.8.0.0/24) from Traefik forwarded headers All monitoring services now publicly accessible via subdomains: - grafana.michaelschiemer.de (with Grafana native auth) - prometheus.michaelschiemer.de (with Basic Auth) - portainer.michaelschiemer.de (with Portainer native auth) All services use Let's Encrypt SSL certificates via Traefik.
132 lines
4.0 KiB
PHP
132 lines
4.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use App\Framework\QrCode\QrCodeGenerator;
|
|
use App\Framework\QrCode\Structure\FormatInformation;
|
|
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeConfig;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeVersion;
|
|
use App\Framework\QrCode\ValueObjects\EncodingMode;
|
|
|
|
echo "=== Format Information Debug ===\n\n";
|
|
|
|
$testData = 'HELLO WORLD';
|
|
$config = new QrCodeConfig(
|
|
version: QrCodeVersion::fromNumber(1),
|
|
errorCorrectionLevel: ErrorCorrectionLevel::M,
|
|
encodingMode: EncodingMode::BYTE
|
|
);
|
|
|
|
$matrix = QrCodeGenerator::generate($testData, $config);
|
|
|
|
// Read format information from matrix
|
|
$formatCols = [0, 1, 2, 3, 4, 5, 7, 8, 20, 19, 18, 17, 16, 15, 14];
|
|
$formatH = '';
|
|
foreach ($formatCols as $col) {
|
|
$formatH .= $matrix->getModuleAt(8, $col)->isDark() ? '1' : '0';
|
|
}
|
|
|
|
echo "Format Information (Horizontal): {$formatH}\n";
|
|
echo "Binary: " . str_pad(decbin(bindec($formatH)), 15, '0', STR_PAD_LEFT) . "\n";
|
|
echo "Decimal: " . bindec($formatH) . "\n\n";
|
|
|
|
// Unmask with XOR mask
|
|
$xorMask = "101010000010010";
|
|
$unmasked = '';
|
|
for ($i = 0; $i < 15; $i++) {
|
|
$unmasked .= (int)$formatH[$i] ^ (int)$xorMask[$i];
|
|
}
|
|
|
|
echo "Unmasked (XOR with mask): {$unmasked}\n";
|
|
echo "Binary: " . str_pad(decbin(bindec($unmasked)), 15, '0', STR_PAD_LEFT) . "\n";
|
|
echo "Decimal: " . bindec($unmasked) . "\n\n";
|
|
|
|
// Decode
|
|
$ecBits = substr($unmasked, 0, 2);
|
|
$maskBits = substr($unmasked, 2, 5);
|
|
$bchBits = substr($unmasked, 5); // BCH error correction bits
|
|
|
|
echo "EC Level bits: {$ecBits}\n";
|
|
echo "Mask Pattern bits: {$maskBits}\n";
|
|
echo "BCH bits: {$bchBits}\n\n";
|
|
|
|
$ecLevel = match($ecBits) {
|
|
'01' => 'L',
|
|
'00' => 'M',
|
|
'11' => 'Q',
|
|
'10' => 'H',
|
|
default => 'UNKNOWN'
|
|
};
|
|
|
|
$maskPattern = bindec($maskBits);
|
|
|
|
echo "Decoded:\n";
|
|
echo " EC Level: {$ecLevel}\n";
|
|
echo " Mask Pattern: {$maskPattern} (binary: {$maskBits})\n\n";
|
|
|
|
if ($maskPattern > 7) {
|
|
echo "❌ PROBLEM: Mask Pattern {$maskPattern} is invalid (should be 0-7)!\n\n";
|
|
|
|
// Check what the mask bits should be
|
|
echo "Expected mask bits for Level M:\n";
|
|
$expectedMasks = [
|
|
0 => "000",
|
|
1 => "001",
|
|
2 => "010",
|
|
3 => "011",
|
|
4 => "100",
|
|
5 => "101",
|
|
6 => "110",
|
|
7 => "111",
|
|
];
|
|
|
|
foreach ($expectedMasks as $pattern => $bits) {
|
|
echo " Pattern {$pattern}: {$bits}\n";
|
|
}
|
|
|
|
echo "\nActual mask bits: {$maskBits} (5 bits, but should be 3 bits)\n";
|
|
echo "The problem is that we're reading 5 bits instead of 3!\n\n";
|
|
|
|
// Check what the correct format should be
|
|
// Format: [EC(2 bits)][Mask(3 bits)][BCH(10 bits)]
|
|
echo "Correct format structure:\n";
|
|
echo " Bits 0-1: EC Level (2 bits)\n";
|
|
echo " Bits 2-4: Mask Pattern (3 bits)\n";
|
|
echo " Bits 5-14: BCH error correction (10 bits)\n\n";
|
|
|
|
// Try reading only 3 bits for mask
|
|
$maskBits3 = substr($unmasked, 2, 3);
|
|
$maskPattern3 = bindec($maskBits3);
|
|
echo "Mask Pattern (3 bits): {$maskBits3} = {$maskPattern3}\n";
|
|
|
|
if ($maskPattern3 <= 7) {
|
|
echo "✅ This is correct! The mask pattern should be read as 3 bits, not 5!\n";
|
|
}
|
|
} else {
|
|
echo "✅ Mask Pattern is valid\n";
|
|
}
|
|
|
|
// Check what mask pattern was actually used
|
|
echo "\n=== Checking Actual Mask Pattern Used ===\n";
|
|
// We need to check which mask pattern was selected by the evaluator
|
|
// But we can't easily access that from the generated matrix
|
|
// Instead, let's check the format information table
|
|
|
|
$reflection = new \ReflectionClass(FormatInformation::class);
|
|
$formatTable = $reflection->getConstant('FORMAT_INFO_TABLE');
|
|
|
|
echo "Format Information Table for Level M:\n";
|
|
foreach ($formatTable['M'] as $pattern => $bits) {
|
|
$bitsStr = str_pad(decbin($bits), 15, '0', STR_PAD_LEFT);
|
|
echo " Pattern {$pattern}: {$bitsStr} (decimal: {$bits})\n";
|
|
|
|
// Check if this matches our format
|
|
if ($bitsStr === $formatH) {
|
|
echo " ✅ MATCHES!\n";
|
|
}
|
|
}
|
|
|