parseOldNumNat function

List<String> parseOldNumNat(
  1. String secondLineFixed
)

Implementation

List<String> parseOldNumNat(String secondLineFixed) {
  final List<String> result = [];
  // 1) Extract MRZ doc number field and its check digit (positions 1–9 and 10)
  final mrzDocField = secondLineFixed.substring(0, 9);   // [0..8]
  final mrzDocCheck = secondLineFixed.substring(9, 10);  // [9]
  final baseDocNumber = mrzDocField.replaceAll('<', '');

  final docNumberValid = _computeMrzCheckDigit(mrzDocField) == mrzDocCheck;

  // 2) Nationality (positions 11–13)
  final nationalityField = secondLineFixed.substring(10, 13); // [10..12]
  final nationality = fixAlphaOnlyField(nationalityField);
  final nationalityValid = isValidMrzCountry(nationality);

  // 3) Try to extend doc number from the Optional Data / Personal Number
  //    field (positions 29–43 -> [28..42]). Position 44 ([43]) is its check digit.
  final optionalData = secondLineFixed.substring(28, 43);

  // Heuristic: if optional data starts with alphanumerics, treat the very first
  // run (until first '<') as a continuation, up to 3 chars.
  final contRaw = optionalData.split('<').first;
  final contClean = contRaw.replaceAll(RegExp(r'[^A-Z0-9]'), '');
  final continuation = contClean.isEmpty ? '' : contClean.substring(0, contClean.length.clamp(0, 3));

  // Build a "full" doc number (for UIs/DBs that want 9–12 chars).
  // The MRZ check digit STILL only validates the 9-char MRZ field.
  String fullDocNumber = (baseDocNumber + continuation);
  if (fullDocNumber.length > 12) {
    fullDocNumber = fullDocNumber.substring(0, 12);
  }
  // Ensure at least the base 9 remain
  if (fullDocNumber.length < baseDocNumber.length) {
    fullDocNumber = baseDocNumber;
  }

  if(docNumberValid && nationalityValid){
    result.add(fullDocNumber);
    result.add(nationality);
  }

  return result;
}