• 字符编码


    1、ASCII、UTF8、Unicode三种编码方式的区别

     1 private static void ShowCode() {
     2     string[] strArray = { "b", "abcd", "", "甲乙丙丁" };
     3     byte[] buffer;
     4     string mode, back;
     5 
     6     foreach (string str in strArray) {
     7 
     8         for (int i = 0; i <= 2; i++) {
     9             if (i == 0) {
    10                 buffer = Encoding.ASCII.GetBytes(str);
    11                 back = Encoding.ASCII.GetString(buffer, 0, buffer.Length);
    12                 mode = "ASCII";
    13             } else if (i == 1) {
    14                 buffer = Encoding.UTF8.GetBytes(str);
    15                 back = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
    16                 mode = "UTF8";
    17             } else {
    18                 buffer = Encoding.Unicode.GetBytes(str);
    19                 back = Encoding.Unicode.GetString(buffer, 0, buffer.Length);
    20                 mode = "Unicode";
    21             }
    22 
    23             Console.WriteLine("Mode: {0}, String: {1}, Buffer.Length: {2}",
    24                 mode, str, buffer.Length);
    25 
    26             Console.WriteLine("Buffer:");
    27             for (int j = 0; j <= buffer.Length - 1; j++) {
    28                 Console.Write(buffer[j] + " ");
    29             }
    30 
    31             Console.WriteLine("
    Retrived: {0}
    ", back);
    32         }
    33     }
    34 }

    输出为:

    Mode: ASCII, String: b, Buffer.Length: 1
    Buffer: 98
    Retrived: b

    Mode: UTF8, String: b, Buffer.Length: 1
    Buffer: 98
    Retrived: b

    Mode: Unicode, String: b, Buffer.Length: 2
    Buffer: 98 0
    Retrived: b

    Mode: ASCII, String: abcd, Buffer.Length: 4
    Buffer: 97 98 99 100
    Retrived: abcd

    Mode: UTF8, String: abcd, Buffer.Length: 4
    Buffer: 97 98 99 100
    Retrived: abcd

    Mode: Unicode, String: abcd, Buffer.Length: 8
    Buffer: 97 0 98 0 99 0 100 0
    Retrived: abcd

    Mode: ASCII, String: 乙, Buffer.Length: 1
    Buffer: 63
    Retrived: ?

    Mode: UTF8, String: 乙, Buffer.Length: 3
    Buffer: 228 185 153
    Retrived: 乙

    Mode: Unicode, String: 乙, Buffer.Length: 2
    Buffer: 89 78
    Retrived: 乙

    Mode: ASCII, String: 甲乙丙丁, Buffer.Length: 4
    Buffer: 63 63 63 63
    Retrived: ????

    Mode: UTF8, String: 甲乙丙丁, Buffer.Length: 12
    Buffer: 231 148 178 228 185 153 228 184 153 228 184 129
    Retrived: 甲乙丙丁

    Mode: Unicode, String: 甲乙丙丁, Buffer.Length: 8
    Buffer: 50 117 89 78 25 78 1 78
    Retrived: 甲乙丙丁

    大体上可以得出这么几个结论:

    • ASCII不能保存中文(貌似谁都知道=_-`)。
    • UTF8是变长编码。在对ASCII字符编码时,UTF更省空间,只占1个字节,与ASCII编码方式和长度相同;Unicode在对ASCII字符编码时,占用2个字节,且第2个字节补零。
    • UTF8在对中文编码时需要占用3个字节;Unicode对中文编码则只需要2个字节。

    (以上转载自http://www.tracefact.net/CSharp-Programming/Network-Programming-Part2.aspx

    2 escape与unescape

    2.1

    escape

      该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / 。其他所有的字符都会被转义序列替换。

    1  escape('abddd<br />');  // "abddd%3Cbr%20/%3E"
    2  'abddd<br />'.length;   // 11
    3  "abddd%3Cbr%20/%3E".length; // 17
    4  
    5  escape('ab<>cd实力');   // "ab%3C%3Ecd%u5B9E%u529B"
    6  'ab<>cd实力'.length;     // 8
    7  "ab%3C%3Ecd%u5B9E%u529B".length; // 22

    unescape

      该函数的工作原理是这样的:通过找到形式为 %xx 和 %uxxxx 的字符序列(x 表示十六进制的数字),用 Unicode 字符 u00xx 和 uxxxx 替换这样的字符序列进行解码。

    1 unescape('abddd%3Cbr%20/%3E'); // "abddd<br />"
    2 unescape('ab%3C%3Ecd%u5B9E%u529B'); // "ab<>cd实力"

      需要注意,javascript中字符串是以Unicode编码形式存储,因此,escape与unescape是将字符在转义字符与Unicode字符间转换(注意转义字符也是已Unicode形式存储)。

    2.2

      另外两种编解码方式(encodeURI与decodeURI、encodeURIComponent与decodeURIComponent)也类似,即转化为转义字符。他们的区别如下:

    encodeURI:

      该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。

      该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的:;/?:@&=+$,#

    encodeURIComponent:

      该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。

      其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。

    另外一个与escape的不同之处是,encodeURI 与 encodeURIComponent 采用uft-8对字符串进行编码,如下

    1 escape('ab<>cd实力')    // "ab%3C%3Ecd%u5B9E%u529B"
    2 encodeURI('ab<>cd实力') // "ab%3C%3Ecd%E5%AE%9E%E5%8A%9B"
    3 encodeURIComponent('ab<>cd实力')    // "ab%3C%3Ecd%E5%AE%9E%E5%8A%9B"

    (以上参考自http://www.w3school.com.cn/

    3、数据传输

      前台页面与后台服务器数据传输时(通过http request与response),只能传输ASCII字符集(如url、post的数据),因此,在交互数据时,如果包含其他字符(如中文字符),需对字符进行编码。

      前台页面:escape与unescape等。

      后台:HttpUtility.UrlEncode与HttpUtility.UrlDecode, 且编码或解码均采用utf-8。

      注:前台页面在向服务器传输数据时,不能显示包含html标签,否则会报错:

      "异常详细信息: System.Web.HttpRequestValidationException: 从客户端(ExportField="<form method="post" ...")中检测到有潜在危险的 Request.Form 值。"

      解决方法为进行字符编码(如escape)。

  • 相关阅读:
    Vim Tricks
    刘洋-从国内三本到牛津博士
    Pandas 学习笔记
    Netbeans and Remote Host for C/C++ Developing
    排序引论
    分枝定界法解0/1背包问题
    部署WEB项目到服务器(三)安装mysql5或者mysql8到linux服务器(Ubuntu)详解
    部署WEB项目到服务器(二)安装tomcat到linux服务器(Ubuntu)详解
    部署WEB项目到服务器(一)安装java到linux服务器(Ubuntu)详解
    FIleZilla连接linux(Ubuntu)服务器的相关问题
  • 原文地址:https://www.cnblogs.com/MattCheng/p/4310736.html
Copyright © 2020-2023  润新知