setModuleAt($darkModuleRow, 8, Module::dark()); // Step 2: Encode data $bits = ''; $bits .= '0100'; // Mode indicator (Byte) $bits .= str_pad(decbin(strlen($data)), 8, '0', STR_PAD_LEFT); // Character count for ($i = 0; $i < strlen($data); $i++) { $bits .= str_pad(decbin(ord($data[$i])), 8, '0', STR_PAD_LEFT); } // Terminator $ecInfo = ReedSolomonEncoder::getECInfo(1, 'M'); $requiredBits = $ecInfo['dataCodewords'] * 8; $terminatorLength = min(4, max(0, $requiredBits - strlen($bits))); $bits .= str_repeat('0', $terminatorLength); // Pad to multiple of 8 $remainder = strlen($bits) % 8; if ($remainder !== 0) { $bits .= str_repeat('0', 8 - $remainder); } // Pad bytes $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 codewords $reedSolomon = new ReedSolomonEncoder(); $ecCodewords = $reedSolomon->encode($dataCodewords, $ecInfo['ecCodewords']); // Merge all codewords $allCodewords = array_merge($dataCodewords, $ecCodewords); echo "=== Encoded Data ===\n"; echo "Mode + Count + Data: " . substr($bits, 0, min(60, strlen($bits))) . "...\n"; echo "Total data codewords: " . count($dataCodewords) . "\n"; echo "Total EC codewords: " . count($ecCodewords) . "\n"; echo "First 4 data codewords: "; for ($i = 0; $i < min(4, count($dataCodewords)); $i++) { echo str_pad(decbin($dataCodewords[$i]), 8, '0', STR_PAD_LEFT) . " "; } echo "\n\n"; // Expected encoding echo "=== Expected Bit Sequence ===\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"; echo "Combined first: " . substr($bits, 0, 64) . "\n\n"; // Step 3: Place data bits (simplified - just show first few positions) echo "=== Data Placement Analysis ===\n"; function isOccupied(int $row, int $col, int $size, int $version): bool { // Finder patterns + separators if ( ($row <= 8 && $col <= 8) || ($row <= 8 && $col >= $size - 8) || ($row >= $size - 8 && $col <= 8) ) { return true; } // Timing if ($row === 6 || $col === 6) { return true; } // Dark module if ($row === (4 * $version + 9) && $col === 8) { return true; } return false; } $size = 21; $placementOrder = []; $bitIdx = 0; // Simulate placement order 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 (!isOccupied($row, $currentCol, $size, 1)) { if ($bitIdx < 64) { // Only track first 64 bits $placementOrder[] = [ 'index' => $bitIdx, 'row' => $row, 'col' => $currentCol, 'bit' => $bits[$bitIdx] ?? '0' ]; } $bitIdx++; } } } } echo "First 16 bit placements:\n"; echo "Idx Row Col Bit Expected\n"; for ($i = 0; $i < min(16, count($placementOrder)); $i++) { $p = $placementOrder[$i]; $expected = substr($bits, $i, 1); $match = $p['bit'] === $expected ? '✓' : '✗'; printf("%2d %2d %2d %s %s %s\n", $p['index'], $p['row'], $p['col'], $p['bit'], $expected, $match); } echo "\n=== Conclusion ===\n"; echo "If all bits match '✓', data placement is correct.\n"; echo "If bits don't match, there's a placement order problem.\n"; echo "Next: Check mask pattern application.\n";