UTF7,BigEndianUnicode,Unicode,Default,ASCII,UTF8,UTF32与GB2312

lilunlil 2020-02-07 07:12:48
先说结论,Encoding下面有7个儿子,
其中6个分别是:UTF7,BigEndianUnicode,Unicode,Default,ASCII,UTF8,UTF32
还有一个最重要的儿子:ANSI,这个儿子下面又有140个儿子,其中一个是 ”简体中文(GB2312)“

---------------------------------割--------------------------------
结合System.Text.Encoding类,说下发现过程
由属性
        public static Encoding UTF7 { get; }
public static Encoding BigEndianUnicode { get; }
public static Encoding Unicode { get; }
public static Encoding Default { get; }
public static Encoding ASCII { get; }
public static Encoding UTF8 { get; }
public static Encoding UTF32 { get; }

知道编码方式有6种,而Default肯定获得的是这6种的其中一种;
运行后发现获得的“简体中文(GB2312)“,还真不是上述6种之一,
度娘知“简体中文(GB2312)”是ANSI其中的一种;
由此知,ANSI是Encoding的一种编码方式(文后附参考文献),只是不知道为什么原始属性中没列出。

二、于是想知道ANSI到底有多少儿子,在Encoding中找到了GetEncodings方法,运行后
列出了140种。

附件一:
C# 运行代码

string Str = "案";
Console.WriteLine("编码ASCII为" + HttpUtility.UrlEncode(Str, System.Text.Encoding.ASCII));
Console.WriteLine("编码BigEndianUnicode为" + HttpUtility.UrlEncode(Str, System.Text.Encoding.BigEndianUnicode));
Console.WriteLine("编码Default为" + HttpUtility.UrlEncode(Str, System.Text.Encoding.Default));
Console.WriteLine("编码Unicode为" + HttpUtility.UrlEncode(Str, System.Text.Encoding.Unicode));
Console.WriteLine("编码UTF32为" + HttpUtility.UrlEncode(Str, System.Text.Encoding.UTF32));
Console.WriteLine("编码UTF7为" + HttpUtility.UrlEncode(Str, System.Text.Encoding.UTF7));
Console.WriteLine("编码UTF8为" + HttpUtility.UrlEncode(Str, System.Text.Encoding.UTF8));

Console.WriteLine("编码UTF32为" + HttpUtility.UrlEncode(Str, System.Text.Encoding.UTF32));
Console.WriteLine("----------------------------------------------------------");
var DefaultCode = System.Text.Encoding.Default;
Console.WriteLine(DefaultCode.BodyName);

Console.WriteLine("----------------------------------------------------------");
var ss = System.Text.Encoding.GetEncodings();
Console.WriteLine($"共{ss.GetLength(0).ToString() }种。");
foreach (var item in ss)
{
Console.WriteLine($"{item.Name }\t{item.CodePage }\t{item.GetEncoding()}");
}

运行结果:



二、参考文献:

来自链接:https://www.iteye.com/blog/wallimn-539595

最后,虽然是付出了一下午努力得出的结论;
但总感觉心虚,觉得上面说法不对(第六感),
请各位大神确认一下。
...全文
234 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
lilunlil 2020-02-08
  • 打赏
  • 举报
回复
引用 1 楼 github_36000833 的回复:
用UTF-16来表示就是: 用UTF-32来表示就是: 用BigEndianUnicode来表示就是:。 用UTF8表示就是: 用GB2312表示就是: 用GB18030表示就是:
谢谢,看完了又琢磨了好久,才明白为何你开头用的“鼓励”二字.... 敢情正确的表述应该是:Encoding下面有140个儿子,其中有6个是全球范围内常用的UTF7,BigEndianUnicode,Unicode,Default,ASCII,UTF8,UTF32,有1个国内常用的,叫GB2312。 这回理解对了吧?
fanruinet 2020-02-08
  • 打赏
  • 举报
回复
所以ANSI也不是最重要的儿子,而是应该被遗弃的儿子
github_36000833 2020-02-08
  • 打赏
  • 举报
回复
鼓励。 所谓的编码,就是把一个字符用一种方法表示出来,比如我自己发明: 一:0001 二:0002 九:0003 十:0010 你:1234 我:1235 它:1236 ... 也一种编码。但这种编码流行不来,只有我自己在使用。 有些大家经常使用,比较知名的编码,就被收录到Encoding的静态属性下,也就是提到的七种Encoding。 这七种里面,有4种完全支持Unicode(后面解释): Encoding.Unicode (名字实际有误,会误导,应该写成Encoding.UTF16) Encoding.BigEndianUnicode Encoding.UTF8 Encoding.UTF32 其他三种中,ASCII和UTF7是历史遗留编码,不能完全表示所有Unicode的码点。 而Encoding.Default实际上不是具体的一种编码,它是当前机器的MBCS的代码页(也是历史遗留造成的)决定的。 所有它可能是iso-8859-1,也可能是gb2312,将来也可能是UTF8等等。 旧的系统(比如Windows3.0)只支持某些编码,需要知道编码方式,这就是当前机器MBCS的代码页的由来。但这种方法通用性很差。随着技术的进步,人们意识到需要有个统一的码点方案,这就是Unicode的出现。Unicode也可以叫做统一码 - 在Unicode下,具体的一个字符的码点是固定的,比如(如果你第三行看不到字符,可能你的系统/浏览器不支持): 的:U+7684 A: U+0041 💕:U+1F495 用UTF-16来表示就是: 的:Encoding.Unicode.GetString(new byte[]{ 0x84, 0x76 }); A: Encoding.Unicode.GetString(new byte[] { 0x41, 0x00 }); 💕:Encoding.Unicode.GetString(new byte[] { 0x3D, 0xD8, 0x95, 0xDC }); 可以看到,UTF-16下,大部分编码可以用两个字节表示,它就直接用了码点的数字,比如{ 0x41, 0x0 }就是0x0041,{ 0x84, 0x76 }就是0x7684。但是,有些码点两个字节放不下,比如那个U+1F495,UFT-16就使用了特定的前缀表示需要4个字节。有兴趣的朋友可以自行参考UTF-16编码。 用UTF-32来表示就是: 的:Encoding.UTF32.GetString(new byte[]{ 0x84, 0x76, 0x00, 0x00 }); A: Encoding.UTF32.GetString(new byte[] { 0x41, 0x00, 0x00, 0x00 }); 💕:Encoding.UTF32.GetString(new byte[] { 0x95, 0xF4, 0x01, 0x00 }); UTF-32固定用32比特,4个字节来表示码点,可以和Unicode码点直接转换。比如{ 0x95, 0xF4, 0x01, 0x00 }就是U+1F495 用BigEndianUnicode来表示就是:。 的:Encoding.BigEndianUnicode.GetString(new byte[]{ 0x76, 0x84 }); A: Encoding.BigEndianUnicode.GetString(new byte[] { 0x00, 0x41 }); 💕:Encoding.BigEndianUnicode(new byte[] { 0xD8, 0x3D, 0xDC, 0x95, }); BigEndian表示“大端在前”,就是在每16比特内,大端字节在前。有兴趣的朋友自行和UTF-16比较。 用UTF8表示就是: 的:Encoding.UTF8.GetString(new byte[] { 0xE7, 0x9A, 0x84 }); A: Encoding.UTF8.GetString(new byte[] { 0x41 }); 💕:Encoding.UTF8.GetString(new byte[] { 0xF0, 0x9F, 0x92, 0x95 }); UTF8是变长编码,传统的Ascii字符如果在127以内,都可以用一个字节表示,所以{ 0x41 }表示U+0041。 很多字符在UTF8可以编码为两个字节,但UTF8的中文编码效率不高,往往要用3个字节表示。有兴趣的朋友可以自行参阅UTF8标准。 用GB2312表示就是: 的:Encoding.GetEncoding("GB2312").GetString(new byte[] { 0xB5, 0xC4 }); A: Encoding.GetEncoding("GB2312").GetString(new byte[] { 0x41 }); 💕:<无法表示> GB2312没有完全支持Unicode,因此无法表示U+1F495。但GB2312的优点是对常用中文支持很好,只要两个字节。也一定上兼容Ascii,可以用一个字节来支持常用的字母和数字。 用GB18030表示就是: 的:Encoding.GetEncoding("GB18030").GetString(new byte[] { 0xB5, 0xC4 }); A: Encoding.GetEncoding("GB18030").GetString(new byte[] { 0x41 }); 💕:Encoding.GetEncoding("GB18030").GetString(new byte[] { 0x94, 0x39, 0xd8, 0x33 }); GB18030用来替代GB2312,它支持Unicode。
fanruinet 2020-02-08
  • 打赏
  • 举报
回复
你引用的参考文献对ANSI的理解有点问题。 ANSI code pages就是Windows code pages,在Windows里ANSI编码指的是除了Unicode编码以外所有的编码。而且ANSI这个名称是一个误用(misnomer)。 ANSI应用程序指的是哪些不是为Unicode编写的应用程序(非Unicode程序),具体来说就是用char *单字节字符串,并调用相应的单字节API(例如: size_t strlen ( const char * str ); )的应用程序。与此相对的是使用wchar_t *双字节字符串,并调用的是双字节API(一般带个w开头,例如: size_t wcslen (const wchar_t* wcs); 的Unicode应用程序。 ANSI应用程序依赖于Windows的默认code page,因此同样的数据可能在不同的电脑上表示的意义不同。这个设置在控制面板->时钟和区域->区域->管理选项卡->非Unicode程序的语言 里面修改。 ANSI既有单字节编码,如code page 1252,也有双字节编码,例如GB2312(code page 936),参考文献对此理解不准确。 Unicode应用程序可以保证相同的数据在所有的电脑上显示相同意义的字符。 .NET的String是Unicode字符串。
github_36000833 2020-02-08
  • 打赏
  • 举报
回复
引用 2 楼 lilunlil 的回复:
... 谢谢,看完了又琢磨了好久,才明白为何你开头用的“鼓励”二字.... ...
是真心鼓励。 原创的技术分享值得鼓励,特别看到有思考,有引用的文章。 阅读者可以重复你的试验,有机会借鉴和修正,对技术理解和观点。 至于常用编码,个人觉得UTF8,UTF16(即微软说的Encoding.Unicode),称得上常用。 UTF7几乎已经死寂了,它以前是用来克服email中不能正常显示的问题。 ASCII的范围太小,几十岁的老协议可能还用。 UTF32不流行,一个字符要用4个字节编码,浪费很大。

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧