1、C#实现Url编码和解码
System.Web.HttpUtility.HtmlEncode(str);
System.Web.HttpUtility.HtmlDecode(str);
System.Web.HttpUtility.UrlEncode(str);
System.Web.HttpUtility.UrlDecode(str);
编码时可以指定编码的
System.Web.HttpUtility.UrlEncode(str,System.Text.Encoding.Unicode);
System.Web.HttpUtility.UrlEncode(str,System.Text.Encoding.UTF8);
System.Web.HttpUtility.UrlEncode(str,System.Text.Encoding.GetEncoding( "GB2312 "));
解码也可以指定编码的
System.Web.HttpUtility.UrlDecode(str,System.Text.Encoding.Unicode);
System.Web.HttpUtility.UrlDecode(str,System.Text.Encoding.UTF8);
System.Web.HttpUtility.UrlDecode(str,System.Text.Encoding.GetEncoding( "GB2312 "));
2、C#关于编码、解码相关问题
编码、解码技术是我们在程序中开发中经常使用到的,对一些敏感信息的存储,比如密码之类的,我们一般是不会直接以明文直接存储到数据库的,而是会通过各种算法,可以是现成的MD5(一种散列算法)、或者是Hash算法+Salt(混淆因子),甚至是自己定义的一套算法进行加解密。这里不想阐述加解密技术,在之前的一篇博客当中,简单列举了两种基本方法,见.NET加解密技术。这里重点讲解一下编码、解码以及乱码的相关问题。
我们先看一个简单的例子:
正是由于ascii码的局限性,不能表示世界上各种语言和符号,因此ISO(国际标准化组织)推出了unicode编码,它可以容纳世界上所有的文字和字符。
有些时候,可能编码会是这样子的:\u4e2d\u56fd
而我们可以这样来处理:
项目开发中经常会有出现乱码的情况,这就是由于两端(服务端、请求端)编解码的方式不一致造成的。比如服务端是utf-8编码,而在客户端以gbk接收,那么就会出现乱码。所以解决乱码这个问题,思路就是从对方的编码方式入手,弄清楚对方的编码是什么编码,我这边就以什么编码来解码。这个解决问题的思路,在我实际项目开发过程中屡试不爽。
比如我们经常会用到web页面导出excel的问题。代码如下:
经过HttpUtility.UrlEncode方法进行编码之后,在IE浏览器下弹出的excel下载对话框中显示的文件名就不会显示乱码,而显示正常的汉字了。对应的方法是HttpUtility.UrlDecode方法,进行解密。这两个方法在web开发编解码当中会用到。
比如:
最后附一个我几年前曾经在实际项目开发中遇到过的一个问题。
当时也是很着急,花了一天时间也没有解决那个问题,老是得不到正确的结果。当时的情况是对方将图片转变为字节数组,然后对这个字节数组进行base64编码之后再对新的字符串进行utf-8编码,最后封装成xml文档。当然这个过程是我推断的,因为当时并不知道真实的情况,只是调用对方提供的webservice。一般来说,对于中文的编码还是以utf-8、gbk、gb2312等编码为主。对方提供的开发文档当中并没有提及编码方式,最后经过实验,用utf-8编码方式解决。(其实准确一点来说,当时的情况是不知道是先对字节数组进行utf-8编码还是先对字节数组的base64编码之后得到的一串字符串再进行utf-8编码)
在网络传输和文件操作中,如果数据量很大,需要将其划分为较小的快,此时可能出现一个数据块的末尾是一个不匹配的高代理项,而与其匹配的低代理项在下一个数据块。
这时候使用Encoding的GetBytes方法处理较为麻烦,我们直接使用Encoder处理。
Encoder可以将一组字符编码为一个字节序列。而Decoder可以将已编码的字节序列解码为字符序列。
若要获取的实现的实例 Encoder 类,应用程序应使用 GetEncoder 方法 Encoding 实现。
GetByteCount 方法确定多少个字节进行编码的一组 Unicode 字符和 GetBytes 方法执行实际的编码。 这两种方法的几个版本中有 Encoder 类。 有关详细信息,请参阅Encoding.GetBytes。
一个 Encoder 对象之间维护状态信息对连续调用 GetBytes 或 Convert 方法,以便它可以正确编码字符跨块的序列。 Encoder 还保留尾随字符数据块的末尾,并在下一步编码操作中使用尾随字符。
例如,一个数据块的末尾可能不匹配的高代理项,并且匹配的低代理项可能在下一个数据块中。 因此, GetDecoder 和 GetEncoder 在网络传输和文件操作很有用,因为这些操作通常处理的数据而不是完整的数据流块。
若要获取的实现的实例 Decoder 类,应用程序应使用 GetDecoder 方法 Encoding 实现。
GetCharCount 方法确定有多少个字符导致个字节的序列进行解码和 GetChars 方法执行实际的解码。 这两种方法的几个版本中有 Decoder 类。 有关详细信息,请参阅Encoding.GetChars。
一个 Decoder 对象之间维护状态信息对连续调用 GetChars 或 Convert 方法,因此它可以正确地对跨块的字节序列进行解码。 Decoder 还保留在数据块的末尾的尾部字节,并在下一步的解码操作中使用的尾随字节。
因此, GetDecoder 和 GetEncoder 非常有用的网络传输和文件操作,因为这些操作通常处理的数据而不是完整的数据流块。
1 string str = "在下坂本,有何贵干@@"; 2 Char[] chars = str.ToCharArray(); 3 Debug.Log("String="+new string(chars)); 4 //获得Encoder实例; 5 Encoder encoder = Encoding.UTF8.GetEncoder(); 6 //计算字符序列化需要的字节数组长度; 7 byte[] bytes = new byte[encoder.GetByteCount(chars,0,chars.Length,true)]; 8 //通过GetBytes转为字节序列; 9 encoder.GetBytes(chars, 0, chars.Length, bytes, 0, true); 10 Debug.Log(BitConverter.ToString(bytes)); 11 Debug.Log("Encoding.UTF8.GetString=" + Encoding.UTF8.GetString(bytes)); 12 //获得Decoder实例; 13 Decoder decoder = Encoding.UTF8.GetDecoder(); 14 //计算字节数组对应的字符数组长度; 15 int charSize = decoder.GetCharCount(bytes, 0, bytes.Length); 16 Char[] chs = new char[charSize]; 17 //进行字符转换; 18 int charLength = decoder.GetChars(bytes, 0, bytes.Length, chs, 0); 19 Debug.Log("Decoder Bytes to String =" + new string(chs));
//output:
MSDN Encoder >>> https://msdn.microsoft.com/zh-cn/library/system.text.encoder%28v=vs.110%29.aspx
MSDN Decoder >>> https://msdn.microsoft.com/zh-cn/library/system.text.decoder%28v=vs.110%29.aspx