getSize(); echo "Matrix Size: {$size}x{$size}\n\n"; // Function to check if position is a function pattern function isFunctionPattern(int $row, int $col, int $size, int $version): string { // Finder patterns + separators (9x9 areas) if ( ($row <= 8 && $col <= 8) || // Top-left ($row <= 8 && $col >= $size - 8) || // Top-right ($row >= $size - 8 && $col <= 8) // Bottom-left ) { return 'FINDER'; } // Timing patterns if ($row === 6 || $col === 6) { return 'TIMING'; } // Dark module $darkModuleRow = 4 * $version + 9; if ($row === $darkModuleRow && $col === 8) { return 'DARK'; } // Format information positions // Horizontal: row 8, cols 0-8 and size-8 to size-1 if ($row === 8 && ($col <= 8 || $col >= $size - 8)) { return 'FORMAT'; } // Vertical: col 8, rows 0-8 and size-7 to size-1 if ($col === 8 && ($row <= 8 || $row >= $size - 7)) { return 'FORMAT'; } // Alignment patterns (Version 2+) if ($version >= 2) { $alignmentLocations = AlignmentPattern::getLocations($version); foreach ($alignmentLocations as $alignRow) { foreach ($alignmentLocations as $alignCol) { // Skip if overlaps with finder patterns if ($alignRow <= 8 && $alignCol <= 8) { continue; } if ($alignRow <= 8 && $alignCol >= $size - 8) { continue; } if ($alignRow >= $size - 8 && $alignCol <= 8) { continue; } // Check if within 5x5 alignment pattern if (abs($row - $alignRow) <= 2 && abs($col - $alignCol) <= 2) { return 'ALIGN'; } } } } return 'DATA'; } // Visualize matrix with pattern types echo "=== Matrix Visualization (Pattern Types) ===\n"; echo "Legend: F=Finder, T=Timing, A=Align, D=Dark, X=Format, .=Data(light), #=Data(dark)\n\n"; for ($row = 0; $row < $size; $row++) { for ($col = 0; $col < $size; $col++) { $patternType = isFunctionPattern($row, $col, $size, $version); $isDark = $matrix->getModuleAt($row, $col)->isDark(); $char = match($patternType) { 'FINDER' => 'F', 'TIMING' => 'T', 'ALIGN' => 'A', 'DARK' => 'D', 'FORMAT' => 'X', 'DATA' => $isDark ? '#' : '.', default => '?' }; echo $char . ' '; } echo "\n"; } echo "\n=== Data Region Analysis ===\n"; // Count data modules $dataModules = 0; $darkDataModules = 0; for ($row = 0; $row < $size; $row++) { for ($col = 0; $col < $size; $col++) { if (isFunctionPattern($row, $col, $size, $version) === 'DATA') { $dataModules++; if ($matrix->getModuleAt($row, $col)->isDark()) { $darkDataModules++; } } } } echo "Total data modules: {$dataModules}\n"; echo "Dark data modules: {$darkDataModules}\n"; echo "Light data modules: " . ($dataModules - $darkDataModules) . "\n"; echo "Data dark ratio: " . round(($darkDataModules / $dataModules) * 100, 2) . "%\n\n"; // Show data bits in placement order (zig-zag pattern) echo "=== Data Bits (Zig-Zag Placement Order) ===\n"; echo "First 64 data bits:\n"; $bitIndex = 0; $bits = []; for ($col = $size - 1; $col >= 1; $col -= 2) { // Skip timing column if ($col === 6) { $col--; } // Zig-zag direction $upward = ((int) (($size - 1 - $col) / 2) % 2) === 0; for ($i = 0; $i < $size; $i++) { $row = $upward ? ($size - 1 - $i) : $i; // Check both columns of the pair for ($c = 0; $c < 2; $c++) { $currentCol = $col - $c; if (isFunctionPattern($row, $currentCol, $size, $version) === 'DATA') { $bit = $matrix->getModuleAt($row, $currentCol)->isDark() ? '1' : '0'; $bits[] = $bit; $bitIndex++; if ($bitIndex <= 64) { echo $bit; if ($bitIndex % 8 === 0) { echo " "; } } } } } } echo "\n\n"; // Decode first few bytes echo "=== First Data Bytes (Binary -> Decimal) ===\n"; for ($i = 0; $i < min(8, count($bits) / 8); $i++) { $byte = substr(implode('', $bits), $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 indicator (Byte): 0100\n"; echo "Character count (8 bits): " . str_pad(decbin(strlen($data)), 8, '0', STR_PAD_LEFT) . " = " . strlen($data) . "\n"; echo "Data bytes:\n"; for ($i = 0; $i < strlen($data); $i++) { $byte = ord($data[$i]); $binary = str_pad(decbin($byte), 8, '0', STR_PAD_LEFT); echo " '{$data[$i]}': {$binary} = {$byte}\n"; } echo "\n=== Format Information Analysis ===\n"; echo "Format info should encode: Error Correction Level + Mask Pattern\n"; echo "Located at: row 8 and col 8 (with redundancy)\n\n"; // Extract format information bits $formatBits = []; // Horizontal format info (row 8, skipping timing column at 6) for ($col = 0; $col < 9; $col++) { if ($col === 6) continue; // Skip timing column $formatBits[] = $matrix->getModuleAt(8, $col)->isDark() ? '1' : '0'; } echo "Horizontal format bits: " . implode('', $formatBits) . "\n"; // Vertical format info $formatBitsVertical = []; for ($row = $size - 1; $row >= $size - 7; $row--) { $formatBitsVertical[] = $matrix->getModuleAt($row, 8)->isDark() ? '1' : '0'; } for ($row = 7; $row >= 0; $row--) { if ($row === 6) continue; // Skip timing column $formatBitsVertical[] = $matrix->getModuleAt($row, 8)->isDark() ? '1' : '0'; } echo "Vertical format bits: " . implode('', $formatBitsVertical) . "\n"; echo "\n=== Summary ===\n"; echo "✓ Matrix generated: {$size}x{$size}\n"; echo "✓ Function patterns placed\n"; echo "✓ Data region identified: {$dataModules} modules\n"; echo "✓ First data bits extracted and decoded\n\n"; echo "Next steps for debugging:\n"; echo "1. Compare expected vs actual data encoding\n"; echo "2. Verify format information is correct\n"; echo "3. Check if mask pattern was applied correctly\n"; echo "4. Validate error correction codewords\n";