format('ym'), $batchSeq, $codeSeq, ); return $base.'-'.$this->checksum($base); } /** * Returns 2-char alphanumeric checksum derived from SHA-256 of the * input. Deterministic; designed to catch single-character typos * during manual entry, not as a cryptographic guarantee. */ public function checksum(string $base): string { $hex = hash('sha256', $base); // Convert two hex bytes to base-36 alphanumeric for shorter, // human-readable output. $int = hexdec(substr($hex, 0, 4)); $code = strtoupper(base_convert((string) $int, 10, 36)); return str_pad(substr($code, 0, 2), 2, '0', STR_PAD_LEFT); } public function isValid(string $serial): bool { $parts = explode('-', $serial); if (count($parts) !== 6) { return false; } $checksum = array_pop($parts); $base = implode('-', $parts); return $this->checksum($base) === strtoupper($checksum); } }