export type ParsedMRZDates = { birthDate: string; // yyyy-mm-dd expiryDate: string; // yyyy-mm-dd }; export type MRZScanResult = { documentNumber: string; expiryDate: string; birthDate: string; }; export function normalizeDocumentNumber(docNumber: string): string { return docNumber.toUpperCase().replace(/O/g, "0"); } function calculateCheckDigit(data: string): number { const weights = [7, 3, 1]; const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ<"; let sum = 0; for (let i = 0; i < data.length; i++) { const char = data[i]; const value = chars.indexOf(char); if (value === -1) throw new Error(`Geçersiz karakter: ${char}`); sum += value * weights[i % 3]; } return sum % 10; } function parseMRZDate( dateStr: string, checkDigit: string, referenceYear: number ): string { if (!/^\d{6}$/.test(dateStr) || !/^\d$/.test(checkDigit)) { throw new Error("Geçersiz tarih veya kontrol basamağı formatı."); } const calculated = calculateCheckDigit(dateStr); if (calculated !== parseInt(checkDigit, 10)) { throw new Error(`Kontrol basamağı hatalı (${dateStr} için).`); } const yy = parseInt(dateStr.slice(0, 2), 10); const mm = dateStr.slice(2, 4); const dd = dateStr.slice(4, 6); const century = Math.floor(referenceYear / 100) * 100; let fullYear = century + yy; if (fullYear > referenceYear + 10) { fullYear -= 100; } return `${fullYear}-${mm}-${dd}`; } export function normalizeMRZDates({ birthDate, birthDateCheckDigit, expirationDate, expirationDateCheckDigit, }: { birthDate: string; birthDateCheckDigit: string; expirationDate: string; expirationDateCheckDigit: string; }): ParsedMRZDates { const currentYear = new Date().getFullYear(); const expiryDate = parseMRZDate( expirationDate, expirationDateCheckDigit, currentYear + 10 ); const expiryYear = parseInt(expiryDate.slice(0, 4), 10); const _birthDate = parseMRZDate( birthDate, birthDateCheckDigit, expiryYear - 10 ); return { birthDate: _birthDate, expiryDate, }; }