查找.NET中的哪些编码是ASCII兼容的
实际上是否有任何简单的方法可以找到.NET中的哪些编码与ASCII兼容?
(基于Nyerguds评论中提出的问题。)
我们假设ASCII的标准定义限制为128个字符(即最高有效位为0的字节值)。 Unicode的设计使其前128个代码点对应于它们的ASCII等价物。 由于.NET中char
结构的数值对应于其Unicode代码点(代理除外),我们可以定义一个实用方法,如下所示:
private static readonly byte[] asciiValues = Enumerable.Range(0, 128).Select(b => (byte)b).ToArray(); private static readonly string asciiChars = new string(asciiValues.Select(b => (char)b).ToArray()); public static bool IsAsciiCompatible(Encoding encoding) { try { return encoding.GetString(asciiValues).Equals(asciiChars, StringComparison.Ordinal) && encoding.GetBytes(asciiChars).SequenceEqual(asciiValues); } catch (ArgumentException) { // Encoding.GetString may throw DecoderFallbackException if a fallback occurred // and DecoderFallback is set to DecoderExceptionFallback. // Encoding.GetBytes may throw EncoderFallbackException if a fallback occurred // and EncoderFallback is set to EncoderExceptionFallback. // Both of these derive from ArgumentException. return false; } }
然后我们可以枚举所有.NET编码,如下所示:
var encodings = Encoding.GetEncodings().Select(e => e.GetEncoding()).ToList(); var asciiCompatible = encodings.Where(e => IsAsciiCompatible(e)).ToList(); var nonAsciiCompatbile = encodings.Except(asciiCompatible).ToList(); Console.WriteLine("ASCII compatible: "); foreach (var encodingName in asciiCompatible.Select(e => e.EncodingName).OrderBy(n => n)) Console.WriteLine("* " + encodingName); Console.WriteLine(); Console.WriteLine("Non-ASCII compatible: "); foreach (var encodingName in nonAsciiCompatbile.Select(e => e.EncodingName).OrderBy(n => n)) Console.WriteLine("* " + encodingName);
请注意,此方法并不完全安全。 如果存在多字节编码,它执行连续字节或字符的花式映射 – 例如将0x61
解码为'a'
,将0x62
为'b'
(如ASCII中)但将0x6261
为" "
– 那么此测试将给出错误结果。
在.NET Fiddle( 代码段 )上运行此命令会得到以下结果:
ASCII兼容:
- 阿拉伯语(864)
- 阿拉伯语(ASMO 708)
- 阿拉伯语(DOS)
- 阿拉伯语(ISO)
- 阿拉伯语(Mac)
- 阿拉伯语(Windows)
- 波罗的海(DOS)
- 波罗的海(ISO)
- 波罗的海(Windows)
- 中欧(DOS)
- 中欧(ISO)
- 中欧(Mac)
- 中欧(Windows)
- 简体中文(EUC)
- 简体中文(GB18030)
- 简体中文(GB2312)
- 简体中文(GB2312-80)
- 简体中文(ISO-2022)
- 简体中文(Mac)
- 繁体中文(Big5)
- 繁体中文(CNS)
- 繁体中文(Eten)
- 繁体中文(Mac)
- 克罗地亚语(Mac)
- 西里尔文(DOS)
- 西里尔文(ISO)
- 西里尔文(KOI8-R)
- 西里尔文(KOI8-U)
- 西里尔文(Mac)
- 西里尔文(Windows)
- 爱沙尼亚语(ISO)
- 法语加拿大人(DOS)
- 希腊语(DOS)
- 希腊语(ISO)
- 希腊语(Mac)
- 希腊语(Windows)
- 希腊语,现代(DOS)
- 希伯来语(DOS)
- 希伯来语(ISO-Logical)
- 希伯来语(ISO-Visual)
- 希伯来语(Mac)
- 希伯来语(Windows)
- IBM5550台湾
- 冰岛语(DOS)
- 冰岛语(Mac)
- ISCII阿萨姆
- ISCII孟加拉语
- ISCII梵文
- ISCII古吉拉特语
- ISCII卡纳达语
- ISCII马拉雅拉姆语
- ISCII Oriya
- ISCII旁遮普语
- ISCII泰米尔语
- ISCII泰卢固语
- 日语(EUC)
- 日语(JIS 0208-1990和0212-1990)
- 日语(Mac)
- 日语(Shift-JIS)
- 朝鲜的
- 韩国语(EUC)
- 韩国人(Johab)
- 韩语(Mac)
- 韩国万松
- 拉丁文3(ISO)
- 拉丁语9(ISO)
- 北欧(DOS)
- OEM西里尔文
- OEM多语言拉丁文I
- OEM美国
- 葡萄牙语(DOS)
- 罗马尼亚语(Mac)
- TCA台湾
- TeleText台湾
- 泰语(Windows)
- 土耳其语(DOS)
- 土耳其语(ISO)
- 土耳其语(Mac)
- 土耳其语(Windows)
- 乌克兰语(Mac)
- Unicode(UTF-8)
- US-ASCII
- 越南语(Windows)
- 王台湾
- 西欧(DOS)
- 西欧(ISO)
- 西欧(Mac)
- 西欧(Windows)
非ASCII兼容:
- 简体中文(HZ)
- 欧罗巴
- 德语(IA5)
- IBM EBCDIC(阿拉伯语)
- IBM EBCDIC(西里尔文俄文)
- IBM EBCDIC(西里尔文塞尔维亚语 – 保加利亚语)
- IBM EBCDIC(丹麦 – 挪威)
- IBM EBCDIC(丹麦 – 挪威 – 欧元)
- IBM EBCDIC(芬兰 – 瑞典)
- IBM EBCDIC(芬兰 – 瑞典 – 欧元)
- IBM EBCDIC(法国)
- IBM EBCDIC(法国 – 欧元)
- IBM EBCDIC(德国)
- IBM EBCDIC(德国 – 欧元)
- IBM EBCDIC(希腊现代)
- IBM EBCDIC(希腊语)
- IBM EBCDIC(希伯来语)
- IBM EBCDIC(冰岛语)
- IBM EBCDIC(冰岛 – 欧元)
- IBM EBCDIC(国际)
- IBM EBCDIC(国际 – 欧元)
- IBM EBCDIC(意大利)
- IBM EBCDIC(意大利 – 欧元)
- IBM EBCDIC(日本片假名)
- IBM EBCDIC(韩语扩展)
- IBM EBCDIC(多语言拉丁语-2)
- IBM EBCDIC(西class牙)
- IBM EBCDIC(西class牙 – 欧元)
- IBM EBCDIC(泰语)
- IBM EBCDIC(土耳其语Latin-5)
- IBM EBCDIC(土耳其语)
- IBM EBCDIC(英国)
- IBM EBCDIC(英国 – 欧元)
- IBM EBCDIC(美国 – 加拿大)
- IBM EBCDIC(美国 – 加拿大 – 欧元)
- IBM Latin-1
- IBM Latin-1
- ISO-6937
- 日语(JIS)
- 日语(JIS-Allow 1字节假名 – SO / SI)
- 日语(JIS-Allow 1字节假名)
- 韩国(ISO)
- 挪威语(IA5)
- 瑞典语(IA5)
- T.61
- 泰语(Mac)
- Unicode (UTF-16)
- Unicode(Big-Endian)
- Unicode(UTF-32 Big-Endian)
- Unicode(UTF-32)
- Unicode(UTF-7)
- 西欧(IA5)