refactor(deployment): Remove WireGuard VPN dependency and restore public service access
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.
This commit is contained in:
158
tests/debug/test-reed-solomon-decoder.php
Normal file
158
tests/debug/test-reed-solomon-decoder.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use App\Framework\QrCode\ErrorCorrection\ReedSolomonEncoder;
|
||||
|
||||
echo "=== Reed-Solomon Decoder Test ===\n\n";
|
||||
|
||||
// Simple Reed-Solomon decoder for verification
|
||||
// This implements a basic syndrome calculation
|
||||
|
||||
class SimpleRSDecoder
|
||||
{
|
||||
private array $gfLog;
|
||||
private array $gfExp;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->initializeGaloisField();
|
||||
}
|
||||
|
||||
private function initializeGaloisField(): void
|
||||
{
|
||||
$this->gfLog = array_fill(0, 256, 0);
|
||||
$this->gfExp = array_fill(0, 512, 0);
|
||||
|
||||
$x = 1;
|
||||
for ($i = 0; $i < 255; $i++) {
|
||||
$this->gfExp[$i] = $x;
|
||||
$this->gfLog[$x] = $i;
|
||||
$x <<= 1;
|
||||
if ($x & 0x100) {
|
||||
$x ^= 0x11d;
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 255; $i < 512; $i++) {
|
||||
$this->gfExp[$i] = $this->gfExp[$i - 255];
|
||||
}
|
||||
}
|
||||
|
||||
private function gfMultiply(int $a, int $b): int
|
||||
{
|
||||
if ($a === 0 || $b === 0) {
|
||||
return 0;
|
||||
}
|
||||
return $this->gfExp[$this->gfLog[$a] + $this->gfLog[$b]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate syndromes for the received codeword
|
||||
* For a valid codeword, all syndromes should be zero
|
||||
*
|
||||
* Standard Reed-Solomon: c(x) = c[0] + c[1]*x + c[2]*x^2 + ... + c[n-1]*x^(n-1)
|
||||
* Evaluate at generator roots: S[i] = c(α^i)
|
||||
*/
|
||||
public function calculateSyndromes(array $codeword, int $ecCodewords): array
|
||||
{
|
||||
$syndromes = array_fill(0, $ecCodewords, 0);
|
||||
|
||||
// Evaluate at generator roots (α^0, α^1, ..., α^(t-1))
|
||||
for ($i = 0; $i < $ecCodewords; $i++) {
|
||||
$syndrome = 0;
|
||||
$alphaPower = $this->gfExp[$i]; // α^i
|
||||
|
||||
// Evaluate polynomial at α^i: sum(codeword[j] * (α^i)^j)
|
||||
$power = 1; // (α^i)^0 = 1
|
||||
for ($j = 0; $j < count($codeword); $j++) {
|
||||
$syndrome ^= $this->gfMultiply($codeword[$j], $power);
|
||||
$power = $this->gfMultiply($power, $alphaPower);
|
||||
}
|
||||
|
||||
$syndromes[$i] = $syndrome;
|
||||
}
|
||||
|
||||
return $syndromes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if codeword is valid (all syndromes are zero)
|
||||
*/
|
||||
public function isValid(array $codeword, int $ecCodewords): bool
|
||||
{
|
||||
$syndromes = $this->calculateSyndromes($codeword, $ecCodewords);
|
||||
foreach ($syndromes as $syndrome) {
|
||||
if ($syndrome !== 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Test with our QR code data
|
||||
echo "Test with QR Code Data:\n\n";
|
||||
|
||||
$dataCodewords = [64, 180, 132, 84, 196, 196, 242, 5, 116, 245, 36, 196, 64, 236, 17, 236];
|
||||
$rs = new ReedSolomonEncoder();
|
||||
$ecCodewords = $rs->encode($dataCodewords, 10);
|
||||
|
||||
echo "Data codewords (16): " . implode(', ', $dataCodewords) . "\n";
|
||||
echo "EC codewords (10): " . implode(', ', $ecCodewords) . "\n\n";
|
||||
|
||||
// Create full codeword
|
||||
$fullCodeword = array_merge($dataCodewords, $ecCodewords);
|
||||
|
||||
echo "Full codeword (26): " . implode(', ', $fullCodeword) . "\n\n";
|
||||
|
||||
// Decode and verify
|
||||
$decoder = new SimpleRSDecoder();
|
||||
$syndromes = $decoder->calculateSyndromes($fullCodeword, 10);
|
||||
|
||||
echo "Syndromes (should all be 0 for valid codeword):\n";
|
||||
$allZero = true;
|
||||
for ($i = 0; $i < count($syndromes); $i++) {
|
||||
$status = $syndromes[$i] === 0 ? '✅' : '❌';
|
||||
if ($syndromes[$i] !== 0) {
|
||||
$allZero = false;
|
||||
}
|
||||
echo " S[{$i}] = {$syndromes[$i]} {$status}\n";
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
if ($allZero) {
|
||||
echo "✅ All syndromes are zero - Reed-Solomon codeword is VALID!\n";
|
||||
echo "\nThis means the EC codewords are correct.\n";
|
||||
echo "If the QR code still doesn't scan, the issue is NOT in Reed-Solomon.\n";
|
||||
} else {
|
||||
echo "❌ Some syndromes are non-zero - Reed-Solomon codeword is INVALID!\n";
|
||||
echo "\nThis means the EC codewords are incorrect.\n";
|
||||
echo "The Reed-Solomon implementation has a bug.\n";
|
||||
}
|
||||
|
||||
// Test with corrupted data
|
||||
echo "\n=== Test with Corrupted Data ===\n";
|
||||
$corruptedCodeword = $fullCodeword;
|
||||
$corruptedCodeword[0] ^= 1; // Flip one bit
|
||||
|
||||
$corruptedSyndromes = $decoder->calculateSyndromes($corruptedCodeword, 10);
|
||||
|
||||
echo "Corrupted codeword (bit 0 flipped):\n";
|
||||
$corruptedAllZero = true;
|
||||
for ($i = 0; $i < count($corruptedSyndromes); $i++) {
|
||||
if ($corruptedSyndromes[$i] !== 0) {
|
||||
$corruptedAllZero = false;
|
||||
}
|
||||
echo " S[{$i}] = {$corruptedSyndromes[$i]}\n";
|
||||
}
|
||||
|
||||
if ($corruptedAllZero) {
|
||||
echo "❌ Corrupted codeword appears valid (decoder bug)\n";
|
||||
} else {
|
||||
echo "✅ Corrupted codeword correctly detected as invalid\n";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user