代码之家  ›  专栏  ›  技术社区  ›  Ryall

学习不同类型的字符编码并在它们之间转换的好资源

  •  2
  • Ryall  · 技术社区  · 17 年前

    有一件事我从未真正理解过,那就是字符编码的概念。在内存和代码中处理编码的方式常常让我感到困惑,因为我只是从互联网上复制了一个示例,而没有真正理解它的功能。我觉得这是一个非常重要而且被忽视的话题,更多的人应该花时间去做正确的事情(包括我自己)。

    我正在寻找一些好的、切中要害的资源来学习不同类型的字符编码并在它们之间进行转换(最好是在C#中)。欢迎使用书籍和在线资源。

    谢谢


    编辑1:

    感谢到目前为止的回复。我特别想了解更多关于.NET如何处理编码的信息。我知道这看起来很模糊,但我真的不知道该问什么。我想我很好奇编码是如何表示的,比如说在C#string类中,以及该类本身是否可以管理不同的编码类型,或者是否有单独的类来实现这一点?

    3 回复  |  直到 6 年前
        1
  •  2
  •   Avi    17 年前

    维基百科对字符编码有一个很好的解释: http://en.wikipedia.org/wiki/Character_encoding

    如果您想了解最流行的字符编码之一UTF-8的详细信息,请阅读 UTF-8 and Unicode FAQ

    而且,正如已经指出的那样, "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)" 是一个非常好的初学者教程。

        2
  •  2
  •   McDowell rahul gupta    17 年前

    我想从这个问题开始: 什么是角色?

    • 码点 . Unicode为每个不一定与任何位/字节形式相关的字符分配一个数字。编码(如UTF-8)定义到字节值的映射。
    • 编码形式 . 每个代码点一个或多个字节,值由使用的编码确定。
    • 字位 . 从一个或多个代码点创建图形。这是演示结束时的内容。

    in.txt 从…起 windows-1252 UTF-8 out.txt .

    using System;
    using System.IO;
    using System.Text;
    public class Enc {
      public static void Main(String[] args) {
        Encoding win1252 = Encoding.GetEncoding(1252);
        Encoding utf8 = Encoding.UTF8;
        using(StreamReader reader = new StreamReader("in.txt", win1252)) {
          using(StreamWriter writer = new StreamWriter("out.txt", false, utf8)) {
            char[] buffer = new char[1024];
            while(reader.Peek() > 0) {
              int r = reader.Read(buffer, 0, buffer.Length);
              writer.Write(buffer, 0, r); 
            }
          }
        }
      }
    }
    

    windows-1252 UTF-16 char 缓冲器然后将缓冲区转换为 .

    代码点

    一些示例代码点:

    • U+0041是 拉丁文大写字母A
    • U+00A3是 磅符号 ()
    • U+042F为零 (Я)
    • 数学FRAKTUR CAPITAL G ()

    无论你在哪里使用字符,它都会以某种形式进行编码。C#使用UTF-16作为其 char type

    您可以将编码视为代码点和字节表示之间的表格映射。

    CODEPOINT       UTF-16BE        UTF-8     WINDOWS-1252
    U+0041 (A)         00 41           41               41
    U+00A3 (£)         00 A3        C2 A3               A3
    U+042F (Ya)        04 2F        D0 AF                -
    U+1D50A      D8 35 DD 0A  F0 9D 94 8A                -
    

    这个 System.Text.Encoding

    字形

    您在屏幕上看到的图形可能由多个代码点构成。字符e-acute(e)可以用两个代码点表示, U+0065和 结合尖锐口音

    (“é”通常由单个代码点U+00E9表示。您可以使用规范化在它们之间切换。不过,并非所有组合序列都有一个等效的单个字符。)

    结论

    • 当您将C#字符串编码为编码时,您正在执行从UTF-16到该编码的转换。
    • 编码可能是有损转换-大多数非Unicode编码只能对现有字符的子集进行编码。
    • 由于并非所有的代码点都可以放入一个C#字符中,因此字符串中的字符数可能大于代码点数,并且代码点数可能大于渲染的图形数。
    • 字符串的“长度”是上下文敏感的,因此您需要知道应用的是什么意思,并使用适当的算法。如何处理这个问题是由您使用的编程语言定义的。
    • 在许多编码中赋予拉丁-1字符相同的值会让一些人产生ASCII的错觉。

    (这篇文章比我预想的要冗长一点,可能比你想要的要多,所以我停下来。我写了一篇更冗长的文章 post on Java encoding here .)

        3
  •  1
  •   Andrew M    17 年前

    有一篇著名的Joel文章“每个软件开发人员绝对、绝对、绝对必须了解Unicode和字符集(没有借口!)” http://www.joelonsoftware.com/articles/Unicode.html

    编辑:虽然这更多的是关于文本格式,但在重读时,我想你对html编码和url编码更感兴趣?用于转义在html或URL中具有重要意义的特殊字符(例如html中的<和>,或URL中的?和=等)