isOcrConfusionPair function

bool isOcrConfusionPair(
  1. String a,
  2. String b
)

Returns true if a and b are characters commonly confused by OCR based on visual similarity of glyph shapes.

Implementation

bool isOcrConfusionPair(String a, String b) {
  final String upper1 = a.toUpperCase();
  final String upper2 = b.toUpperCase();
  if (upper1 == upper2) return true;

  // Symmetric lookup: visual-similarity groups for OCR template matching.
  const Map<String, Set<String>> confusionGroups = {
    'A': {'X', '@'},
    'I': {'L', '1', '!', '|', 'T'},
    'L': {'I', '1', '!', '|', 'B'},
    '1': {'I', 'L', '!', '|'},
    'O': {'0', 'Q', 'D', 'B'},
    '0': {'O', 'Q', 'D', 'B'},
    'S': {'5', '8'},
    '5': {'S', '8'},
    '8': {'S', '5', 'B'},
    'B': {'8', 'D', '0', 'O', 'L'},
    'Z': {'2'},
    '2': {'Z'},
    'T': {'1', 'I', '7', 'F'},
    'G': {'6', '9'},
    '6': {'G'},
    '9': {'G'},
    'N': {'M', 'H'},
    'M': {'N', 'H'},
    'H': {'N', 'M'},
    'U': {'L'},
    'X': {'A'},
    'E': {'O'},
    'F': {'P', 'T'},
    'P': {'F'},
  };

  return confusionGroups[upper1]?.contains(upper2) ??
      confusionGroups[upper2]?.contains(upper1) ??
      false;
}