isOcrConfusionPair function
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;
}