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"; }