namespace Monitor.Backend.Application; /// /// 把「ASN 和组织名」归成几个常见的国内运营商:mobile / telecom / unicom / broadnet;别的是 other(显示组织名)。 /// 只用来挑展示用的图标和中文名。 /// public static class IspClassifier { public const string Mobile = "mobile"; public const string Telecom = "telecom"; public const string Unicom = "unicom"; public const string Broadnet = "broadnet"; public const string Other = "other"; private static readonly HashSet s_mobile = [9808, 24400, 24445, 56040, 56041, 56042, 56044, 56046, 56047, 56048, 132525, 138407]; private static readonly HashSet s_telecom = [4134, 4809, 4811, 4812, 4813, 9394, 17638, 23724, 38283, 58466, 58519, 136188, 137693]; private static readonly HashSet s_unicom = [4808, 4837, 9929, 10099, 17621, 17622, 17623, 17816, 136958, 138421]; private static readonly HashSet s_broadnet = [63838, 140061]; public static (string Key, string Name) Classify(int? asn, string? organization) { if (asn is { } a) { if (s_mobile.Contains(a)) { return (Mobile, "中国移动"); } if (s_telecom.Contains(a)) { return (Telecom, "中国电信"); } if (s_unicom.Contains(a)) { return (Unicom, "中国联通"); } if (s_broadnet.Contains(a)) { return (Broadnet, "中国广电"); } } string org = organization ?? string.Empty; if (Has(org, "china mobile") || Has(org, "cmnet") || Has(org, "中国移动")) { return (Mobile, "中国移动"); } if (Has(org, "china telecom") || Has(org, "chinanet") || Has(org, "中国电信")) { return (Telecom, "中国电信"); } if (Has(org, "china unicom") || Has(org, "cncgroup") || Has(org, "中国联通")) { return (Unicom, "中国联通"); } if (Has(org, "china broadnet") || Has(org, "中国广电")) { return (Broadnet, "中国广电"); } return (Other, Shorten(org)); } private static bool Has(string text, string needle) => text.Contains(needle, StringComparison.OrdinalIgnoreCase); /// 组织名常常很长(「Hangzhou Alibaba Advertising Co.,Ltd.」):去掉公司后缀,最多留 28 个字符。 internal static string Shorten(string organization) { string name = organization.Trim(); foreach (string suffix in new[] { ", Inc.", " Inc.", ", LLC", " LLC", " Co.,Ltd.", " Co., Ltd.", " Co.,Ltd", " Co., Ltd", " Ltd.", " Ltd", " Corporation", " Corp.", " Limited", " GmbH", " B.V.", " S.A." }) { if (name.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)) { name = name[..^suffix.Length].TrimEnd(',', ' '); break; } } return name.Length > 28 ? name[..28].TrimEnd() : name; } }