getModuleAt(8, $col)->isDark() ? '1' : '0'; } $xorMask = "101010000010010"; $unmasked = ''; for ($i = 0; $i < 15; $i++) { $unmasked .= (int)$formatH[$i] ^ (int)$xorMask[$i]; } $maskBits = substr($unmasked, 2, 5); $maskPattern = bindec($maskBits); echo "Decoded Mask Pattern: {$maskPattern}\n"; echo "Mask Bits: {$maskBits}\n\n"; if ($maskPattern > 7) { echo "❌ PROBLEM: Mask Pattern is {$maskPattern}, but should be 0-7!\n"; echo "This means the format information is incorrect.\n"; echo "The mask bits are 5 bits, so max value is 31.\n"; echo "But QR codes only use mask patterns 0-7 (3 bits).\n\n"; // Check what the actual mask pattern should be echo "Checking what mask pattern should be used...\n"; // The mask pattern selection should be based on penalty scoring // Let's check what mask pattern was actually applied } else { echo "✅ Mask Pattern is valid (0-7)\n"; } // Check if we can identify which mask pattern was actually used // by checking the data placement pattern echo "\n=== Checking Data Placement ===\n"; echo "For Version 1, Level M, we have 16 data codewords + 10 EC codewords = 26 total\n"; echo "Each codeword is 8 bits, so 26 * 8 = 208 bits of data\n"; echo "Plus mode (4 bits) + count (8 bits) = 12 bits overhead\n"; echo "Total data bits: 220 bits\n\n"; // Count dark modules in data area (excluding function patterns) $dataAreaDark = 0; $dataAreaTotal = 0; for ($row = 0; $row < 21; $row++) { for ($col = 0; $col < 21; $col++) { // Skip function patterns if ( // Finder patterns ($row <= 8 && $col <= 8) || ($row <= 7 && $col >= 13) || ($row >= 13 && $col <= 7) || // Timing patterns $row === 6 || $col === 6 || // Format info ($row === 8 && ($col <= 8 || $col >= 13)) || ($col === 8 && ($row <= 7 || $row >= 9)) || // Dark module ($row === 13 && $col === 8) ) { continue; } $dataAreaTotal++; if ($matrix->getModuleAt($row, $col)->isDark()) { $dataAreaDark++; } } } echo "Data area modules: {$dataAreaTotal}\n"; echo "Dark modules in data area: {$dataAreaDark}\n"; echo "Light modules in data area: " . ($dataAreaTotal - $dataAreaDark) . "\n"; echo "Dark ratio: " . number_format(($dataAreaDark / $dataAreaTotal) * 100, 2) . "%\n\n"; // For a scannable QR code, the dark ratio should be around 50% // But with masking, it can vary if ($dataAreaDark > 0 && $dataAreaTotal > 0) { echo "✅ Data area has modules\n"; } else { echo "❌ Data area is empty - this is a problem!\n"; }