C#如何对FOX与F0X这类视觉相似字符串进行比较
实现思路
核心原理是先对两个输入字符串做归一化处理:把所有视觉易混的字符统一替换为同一个基准字符,再对处理后的字符串做常规相等判断即可,全程不需要调用数据库,所有映射规则都可以硬编码在代码中。
具体实现步骤
- 第一步:定义视觉相似字符映射表,把所有视觉相近的字符都映射到同一个基准值,比如把大写O、小写o、数字0统一映射为
'0',其他常见易混组合还包括数字1和小写l、大写I,数字2和大写Z,数字5和大写S等,你可以根据自己的需求增减映射规则。 - 第二步:编写通用的字符串归一化方法,遍历原始字符串的每个字符,按映射表替换为基准字符,还可以按需增加大小写统一转换逻辑,忽略大小写差异对比较结果的影响。
- 第三步:将两个待比较的字符串分别做归一化处理后,直接做常规的字符串相等比较,相等即可判定为视觉相似。
C# 代码示例
using System; using System.Collections.Generic; public static class VisualStringComparer { // 视觉相似字符映射表,同组易混字符全部映射到同一个基准字符 private static readonly Dictionary<char, char> SimilarCharMap = new Dictionary<char, char> { // O/0 易混组 {'0', '0'}, {'O', '0'}, {'o', '0'}, // 1/I/l 易混组 {'1', '1'}, {'I', '1'}, {'l', '1'}, {'i', '1'}, // 2/Z 易混组 {'2', '2'}, {'Z', '2'}, {'z', '2'}, // 5/S 易混组 {'5', '5'}, {'S', '5'}, {'s', '5'}, // 8/B 易混组 {'8', '8'}, {'B', '8'}, {'b', '8'}, // 可自行补充其他易混组合,比如9和q、v和u等 }; // 字符串归一化处理 private static string NormalizeString(string input) { if (string.IsNullOrEmpty(input)) return input; char[] result = input.ToCharArray(); for (int i = 0; i < result.Length; i++) { // 存在映射规则就替换为基准字符,否则保留原值 if (SimilarCharMap.TryGetValue(result[i], out char normalizedChar)) { result[i] = normalizedChar; } // 可选逻辑:统一转大写/小写,忽略大小写差异 // result[i] = char.ToUpperInvariant(result[i]); } return new string(result); } // 对外暴露的视觉相似比较方法 public static bool AreVisuallySimilar(string str1, string str2) { // 空值特殊处理 if (str1 == null && str2 == null) return true; if (str1 == null || str2 == null) return false; // 长度不同直接判定为不相似 if (str1.Length != str2.Length) return false; // 归一化后比较是否相等 return NormalizeString(str1) == NormalizeString(str2); } // 测试用例 public static void Main() { Console.WriteLine(AreVisuallySimilar("FOX", "F0X")); // 输出 True Console.WriteLine(AreVisuallySimilar("Hello123", "HeIIoI23")); // 输出 True Console.WriteLine(AreVisuallySimilar("ABC", "ABD")); // 输出 False } }
扩展建议
- 如果需要更高的匹配精度,可以根据你使用的字体场景调整映射表内容,新增对应易混字符对即可。
- 如果需要支持模糊匹配(允许少数字符差异),可以对归一化后的两个字符串计算编辑距离,编辑距离小于设定阈值即可判定为相似,不需要完全相等。
内容的提问来源于stack exchange,提问作者Stockers
相关产品推荐
相关产品推荐

