Files
michaelschiemer/tests/debug/test-qr-before-after-mask.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

191 lines
5.9 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Framework\QrCode\ValueObjects\QrCodeMatrix;
use App\Framework\QrCode\ValueObjects\QrCodeVersion;
use App\Framework\QrCode\ValueObjects\Module;
use App\Framework\QrCode\ValueObjects\ModulePosition;
use App\Framework\QrCode\Structure\FinderPattern;
use App\Framework\QrCode\Structure\TimingPattern;
use App\Framework\QrCode\Structure\AlignmentPattern;
use App\Framework\QrCode\Structure\FormatInformation;
use App\Framework\QrCode\ErrorCorrection\ReedSolomonEncoder;
use App\Framework\QrCode\Masking\MaskEvaluator;
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
echo "=== Before/After Masking Comparison ===\n\n";
$data = "HELLO";
$version = QrCodeVersion::fromNumber(1);
$errorLevel = ErrorCorrectionLevel::M;
// Build matrix up to data placement (before masking)
$matrix = QrCodeMatrix::create($version);
$matrix = FinderPattern::apply($matrix);
$matrix = FinderPattern::applySeparators($matrix);
$matrix = AlignmentPattern::apply($matrix);
$matrix = TimingPattern::apply($matrix);
// Add dark module
$darkModuleRow = 4 * 1 + 9;
$matrix = $matrix->setModuleAt($darkModuleRow, 8, Module::dark());
// Encode data
$bits = '0100'; // Mode
$bits .= str_pad(decbin(strlen($data)), 8, '0', STR_PAD_LEFT); // Count
for ($i = 0; $i < strlen($data); $i++) {
$bits .= str_pad(decbin(ord($data[$i])), 8, '0', STR_PAD_LEFT);
}
// Add padding
$ecInfo = ReedSolomonEncoder::getECInfo(1, 'M');
$requiredBits = $ecInfo['dataCodewords'] * 8;
$terminatorLength = min(4, max(0, $requiredBits - strlen($bits)));
$bits .= str_repeat('0', $terminatorLength);
$remainder = strlen($bits) % 8;
if ($remainder !== 0) {
$bits .= str_repeat('0', 8 - $remainder);
}
$padBytes = ['11101100', '00010001'];
$padIndex = 0;
while (strlen($bits) < $requiredBits) {
$bits .= $padBytes[$padIndex % 2];
$padIndex++;
}
// Convert to codewords
$dataCodewords = [];
for ($i = 0; $i < strlen($bits); $i += 8) {
$byte = substr($bits, $i, 8);
$dataCodewords[] = bindec($byte);
}
// Generate EC
$reedSolomon = new ReedSolomonEncoder();
$ecCodewords = $reedSolomon->encode($dataCodewords, $ecInfo['ecCodewords']);
$allCodewords = array_merge($dataCodewords, $ecCodewords);
// Place data
$size = 21;
$allBits = '';
foreach ($allCodewords as $codeword) {
$allBits .= str_pad(decbin($codeword), 8, '0', STR_PAD_LEFT);
}
$bitIndex = 0;
for ($col = $size - 1; $col >= 1; $col -= 2) {
if ($col === 6) {
$col--;
}
$upward = ((int) (($size - 1 - $col) / 2) % 2) === 0;
for ($i = 0; $i < $size; $i++) {
$row = $upward ? ($size - 1 - $i) : $i;
for ($c = 0; $c < 2; $c++) {
$currentCol = $col - $c;
$position = ModulePosition::at($row, $currentCol);
// Skip function patterns and format info
if ($row <= 8 && $currentCol <= 8) continue;
if ($row <= 8 && $currentCol >= $size - 8) continue;
if ($row >= $size - 8 && $currentCol <= 8) continue;
if ($row === 6 || $currentCol === 6) continue;
if ($row === 8 || $currentCol === 8) continue;
if ($bitIndex < strlen($allBits)) {
$bit = $allBits[$bitIndex];
$module = ($bit === '1') ? Module::dark() : Module::light();
$matrix = $matrix->setModule($position, $module);
$bitIndex++;
}
}
}
}
echo "=== BEFORE Masking ===\n";
echo "First 64 data bits: " . substr($allBits, 0, 64) . "\n";
echo "Decoded bytes:\n";
for ($i = 0; $i < 8; $i++) {
$byte = substr($allBits, $i * 8, 8);
$decimal = bindec($byte);
$char = $decimal >= 32 && $decimal < 127 ? chr($decimal) : '.';
echo " Byte " . ($i + 1) . ": {$byte} = {$decimal} ('{$char}')\n";
}
echo "\n=== Expected Encoding ===\n";
echo "Mode (Byte): 0100\n";
echo "Count (5): 00000101\n";
echo "H (72): 01001000\n";
echo "E (69): 01000101\n";
echo "L (76): 01001100\n";
echo "L (76): 01001100\n";
echo "O (79): 01001111\n";
$expectedStart = '0100' . '00000101' . '01001000' . '01000101' . '01001100' . '01001100' . '01001111';
$actualStart = substr($allBits, 0, strlen($expectedStart));
echo "\nComparison:\n";
echo "Expected: {$expectedStart}\n";
echo "Actual: {$actualStart}\n";
echo ($expectedStart === $actualStart) ? "✅ MATCH!\n" : "❌ MISMATCH!\n";
// Now apply mask
echo "\n=== Applying Mask ===\n";
$maskEvaluator = new MaskEvaluator();
$bestMask = $maskEvaluator->selectBestMask($matrix);
echo "Selected mask pattern: {$bestMask->value}\n";
$maskedMatrix = $maskEvaluator->applyMask($matrix, $bestMask);
// Add format info
$maskedMatrix = FormatInformation::apply($maskedMatrix, $errorLevel, $bestMask->value);
echo "\n=== AFTER Masking ===\n";
// Extract masked bits
$maskedBits = '';
$bitIdx = 0;
for ($col = $size - 1; $col >= 1; $col -= 2) {
if ($col === 6) {
$col--;
}
$upward = ((int) (($size - 1 - $col) / 2) % 2) === 0;
for ($i = 0; $i < $size; $i++) {
$row = $upward ? ($size - 1 - $i) : $i;
for ($c = 0; $c < 2; $c++) {
$currentCol = $col - $c;
if ($row <= 8 && $currentCol <= 8) continue;
if ($row <= 8 && $currentCol >= $size - 8) continue;
if ($row >= $size - 8 && $currentCol <= 8) continue;
if ($row === 6 || $currentCol === 6) continue;
if ($row === 8 || $currentCol === 8) continue;
if ($bitIdx < 64) {
$maskedBits .= $maskedMatrix->getModuleAt($row, $currentCol)->isDark() ? '1' : '0';
$bitIdx++;
}
}
}
}
echo "First 64 masked bits: {$maskedBits}\n";
echo "Decoded bytes:\n";
for ($i = 0; $i < 8; $i++) {
$byte = substr($maskedBits, $i * 8, 8);
$decimal = bindec($byte);
$char = $decimal >= 32 && $decimal < 127 ? chr($decimal) : '.';
echo " Byte " . ($i + 1) . ": {$byte} = {$decimal} ('{$char}')\n";
}