日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

编码解析

發(fā)布時間:2023/12/19 综合教程 27 生活家
生活随笔 收集整理的這篇文章主要介紹了 编码解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Unicode編碼、ASCII碼、UTF-8編碼、GB2312編碼分析總結(jié)

一、由簡到繁順序來總結(jié):

1、ASCII編碼:

在計算機(jī)內(nèi)部,所有的信息最終都表示為一個二進(jìn)制的字符串。每一個二進(jìn)制位(bit)有0和1兩種狀態(tài)。一個字節(jié)(byte)共由八個二進(jìn)制位來組成,共有256種狀態(tài),從 0000000到11111111。

阿拉伯?dāng)?shù)字、英文字母、標(biāo)點(diǎn)符號等這些字符,怎么定義才能讓計算機(jī)識別呢?因?yàn)橛嬎銠C(jī)只識別二進(jìn)制位0和1,所以以上這些字符就必須與二進(jìn)制位(0和1)建立關(guān)系,才能讓計算機(jī)識別。

60年代初,計算機(jī)界制定了一套統(tǒng)一的字符編碼,來表示字符與二進(jìn)制位之間的關(guān)系。這種統(tǒng)一的字符編碼就叫做ASCII編碼。ASCII碼一共規(guī)定了128個字符的編碼,比如空格“SPACE”是32(二進(jìn)制00100000),大寫的字母A是65(二進(jìn)制01000001)。這128個符號(包括32個不能打印出來的控制符號),只占用了一個字節(jié)的后面7位,最前面的1位統(tǒng)一規(guī)定為0。

在英語國家,128個ASCII編碼足以表達(dá)所有字符,但其它非英語國家,字符不是由英文字符組成,這樣就需要增加編碼以表達(dá)這些字符,對于超過128個字符的編碼被稱為非ASCII編碼。比如:在中國,我們用簡體中文,字符編碼方式為GB2312。

2、Unicode編碼:

Unicode是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案。Unicode用數(shù)字0-0x10FFFF來映射這些字符,最多可以容納1114112個字符,或者說有1114112個碼位。碼位就是可以分配給字符的數(shù)字。Unicode只是一個符號集,它只規(guī)定了符號的二進(jìn)制代碼,卻沒有規(guī)定這個二進(jìn)制代碼應(yīng)該如何存儲。Unicode編碼可以表示字符很多,所以采用不定字節(jié)長來表示。UTF-8、UTF-16、UTF-32都是將數(shù)字轉(zhuǎn)換到程序數(shù)據(jù)的編碼方案。

3、UTF-8編碼

UTF-8編碼是Unicode 的實(shí)現(xiàn)方式之一。UTF-8以字節(jié)為單位對Unicode進(jìn)行編碼。它是一種變長的編碼方式。它可以使用1~4個字節(jié)表示一個符號,根據(jù)不同的符號而變化字節(jié)長度。

4、Unicode與UTF-8編碼的轉(zhuǎn)化

從Unicode到UTF-8的編碼方式如下:

  Unicode編碼(16進(jìn)制) ║ UTF-8 字節(jié)流(二進(jìn)制)

  000000 - 00007F ║ 0xxxxxxx

  000080 - 0007FF ║ 110xxxxx 10xxxxxx

  000800 - 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx

  010000 - 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

  UTF-8的特點(diǎn)是對不同范圍的字符使用不同長度的編碼。對于0x00-0x7F之間的字符,UTF-8編碼與ASCII編碼完全相同。UTF-8編碼的最大長度是4個字節(jié)。從上表可以看出,4字節(jié)模板有21個x,即可以容納21位二進(jìn)制數(shù)字。Unicode的最大碼位0x10FFFF也只有21位。

  例1:“漢”字的Unicode編碼是0x6C49。0x6C49在0x0800-0xFFFF之間,使用用3字節(jié)模板了:1110xxxx 10xxxxxx 10xxxxxx。將0x6C49寫成二進(jìn)制是:0110 1100 0100 1001, 用這個比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

UTF-16與UTF-32在此不做介紹。

5、GB2312編碼方式:

我國采用簡體中文,所有中文字符都采用GB2312編碼方式。

GB2312編碼使用的是區(qū)位碼尋字方式,1-9區(qū)存放中文符號,16-55區(qū)存放一級漢字,56-87區(qū)存放二級漢字,如第1個漢字位于16區(qū)的第1位,為:'啊',所以1601,即0x1001就代表了該'啊'的區(qū)位碼值.
區(qū)位碼變換為機(jī)器內(nèi)碼需要分別將區(qū)碼和位碼加0xA0,所以'啊'的機(jī)器內(nèi)碼就是,0xB0A1
4.國際碼=區(qū)位碼+0x2020
機(jī)器內(nèi)碼=國際碼+0x8080 也就是=區(qū)位碼+0xa0a0

6、Unicode編碼與GB2312編碼的關(guān)系

Unicode對漢字進(jìn)行了重新編碼,這和GB2312編碼的方式和順序完全不同,unicode對漢字編碼從0x4E00開始,到0x9FA5為止,所以Unicode和GB2312編碼的轉(zhuǎn)換,就需要一個轉(zhuǎn)換對照表,實(shí)現(xiàn)快速轉(zhuǎn)換。

7、轉(zhuǎn)義字符序列與Unicode編碼關(guān)系
一般轉(zhuǎn)義字符序列用‘\?’表示,?代表所想表達(dá)的字符。如:‘\n’代表換行標(biāo)志。轉(zhuǎn)義字符序列也可以用\U????來表示。????代表16進(jìn)制的Unicode編碼。如:‘\u0066’代表字符‘f‘。

例:"my name\'s GuoXiong"與"my name\u0027s GuoXiong"http://都是表示my name's GuoXiong

C#字符串、字節(jié)數(shù)組和內(nèi)存流間的相互轉(zhuǎn)換
定義string變量為str,內(nèi)存流變量為ms,比特數(shù)組為bt

1.字符串=>比特數(shù)組

(1)byte[] bt=System.Text.Encoding.Default.GetBytes("字符串");

(2)byte[] bt=Convert.FromBase64String("字符串");

補(bǔ)充:

System.Text.Encoding.Unicode.GetBytes(str);
System.Text.Encoding.UTF8.GetBytes(str);
System.Text.Encoding.GetEncoding("gb2312").GetBytes(str); //指定編碼方式

string str = "中國?ss123?";
byte[] bytes = System.Text.Encoding.Default.GetBytes(str); //gb2312編碼 漢字占2個字節(jié)、英文字母占1個字節(jié) bytes長度為12
string s = System.Text.Encoding.Default.GetString(new byte[] { bytes[0],bytes[1] });//解碼后為“中”

byte[] bytes = {97, 98, 99, 100, 101, 102};
string str = System.Text.Encoding.ASCII.GetString(bytes); //結(jié)果為:abcdef ASCII碼表

常用方法:

GetString 已重載。 在派生類中重寫時,將一個字節(jié)序列解碼為一個字符串。
GetChars 已重載。 在派生類中重寫時,將一個字節(jié)序列解碼為一組字符。
GetBytes 已重載。 在派生類中重寫時,將一組字符編碼為一個字節(jié)序列。

GetByteCount 已重載。 在派生類中重寫時,計算對一組字符進(jìn)行編碼所產(chǎn)生的字節(jié)數(shù)。
GetCharCount 已重載。 在派生類中被重寫時,計算對字節(jié)序列進(jìn)行解碼所產(chǎn)生的字符數(shù)。

GetDecoder 在派生類中重寫時,獲取一個解碼器,該解碼器將已編碼的字節(jié)序列轉(zhuǎn)換為字符序列。
GetEncoder 在派生類中重寫時,獲取一個解碼器,該解碼器將Unicode字符序列轉(zhuǎn)換為已編碼的字節(jié)序列

2.比特數(shù)組 => 字符串

(1)string str=System.Text.Encoding.Default.GetString(bt);

(2)string str=Convert.ToBase64String(bt);

3.字符串 => 流

(1)MemoryStream ms=new MemoryStream(System.Text.Encoding.Default.GetBytes("字符串"));

(2)MemoryStream ms=new MemoryStream(Convert.FromBase64String("字符串"));

4.流 => 字符串

(1)string str=Convert.ToBase64String(ms.ToArray());

(2)string str=System.Text.Encoding.Default.GetString(ms.ToArray());

5.比特數(shù)組 => 流

(1)MemoryStream ms=new MemoryStream(bt);

(2)MemoryStream ms=new MemoryStream();ms.Read(bt,0,bt.Lenght);

6.流 => 比特數(shù)組

(1)byte[] bt=ms.ToArray();

(2)MemoryStream ms=new MemoryStream();ms.Write(bt,0,ms.Length);

1、兩種不同的方法計算字符串的長度

string strTmp = "wk986王克東";

int i = System.Text.Encoding.Default.GetBytes(strTmp).Length; //算漢字的長度
int j = strTmp.Length; //不算漢字的長度

Console.WriteLine("字符串{0},算漢字的長度:{1},不算漢字長度:{2}", strTmp,i,j);

//轉(zhuǎn)換成數(shù)組計算數(shù)組的長度

byte[] bytStr = System.Text.Encoding.Default.GetBytes(strTmp);
int len = bytStr.Length;
Console.WriteLine("字符串長度:"+len.ToString());
Console.Read();

2、System.Text.StringBuilder("")

和字符串“+”是不一樣的,在C#中,字符串是“引用”類型,每加一個是重新建立了一個字符串,當(dāng)字符串特別大的時候,性能消耗大,所以要用StringBuilder。

System.Text.StringBuilder sb = new System.Text.StringBuilder("");
sb.Append("中華");
sb.Append("人民");
sb.Append("共和國");
Console.WriteLine(sb);

//判斷漢字個數(shù)

private int ChkGBKLen(string str)
{
System.Text.ASCIIEncoding n = new System.Text.ASCIIEncoding();
byte[] b = n.GetBytes(str);
int l = 0;
for (int i = 0; i <= b.Length - 1; i++)
{
if (b[i] == 63) //判斷是否為漢字或全腳符號
{
l++;
}
}
return l;
}

C#中流,字節(jié),字符,字符串

首先要明白它們本身是由什么組成的:

流:二進(jìn)制

字節(jié):無符號整數(shù)

字符:Unicode編碼字符

字符串:多個Unicode編碼字符

那么在.net下它們之間如何轉(zhuǎn)化呢?

一般是遵守以下規(guī)則:

流->字節(jié)數(shù)組->字符數(shù)組->字符串

下面就來具體談?wù)勣D(zhuǎn)化的語法:

流->字節(jié)數(shù)組

MemoryStream ms = new MemoryStream();

byte[] buffer = new byte[ms.Length];

ms.Read(buffer, 0, (int)ms.Length);

字節(jié)數(shù)組->流

byte[] buffer = new byte[10];

MemoryStream ms = new MemoryStream(buffer);

字節(jié)數(shù)組->字符數(shù)組

1.

byte[] buffer = new byte[10];

char[] ch = new ASCIIEncoding().GetChars(buffer);

//或者:char[] ch = Encoding.UTF8.GetChars(buffer)

2.

byte[] buffer = new byte[10];

char[] ch = new char[10];

for(int i=0; i<buffer.Length; i++)

{

ch[i] = Convert.ToChar(buffer[i]);

}

字符數(shù)組->字節(jié)數(shù)組

1.

char[] ch = new char[10];

byte[] buffer = new ASCIIEncoding().GetBytes(ch);

//或者:byte[] buffer = Encoding.UTF8.GetBytes(ch)

2.

char[] ch = new char[10];

byte[] buffer = new byte[10];

for(int i=0; i<ch.Length; i++)

{

buffer[i] = Convert.ToByte(ch[i]);

}

字符數(shù)組->字符串

char[] ch = new char[10];

string str = new string(ch);

字符串->字符數(shù)組

string str = "abcde";

char[] ch=str .ToCharArray();

字節(jié)數(shù)組->字符串

byte[] buffer = new byte[10];

string str = System.Text.Encoding.UTF8.GetString(buffer);

//或者:string str = new ASCIIEncoding().GetString(buffer);

字符串->字節(jié)數(shù)組

string str = "abcde";

byte[] buffer=System.Text.Encoding.UTF8.GetBytes(str);

//或者:byte[] buffer= new ASCIIEncoding().GetBytes(str);

說明:主要就是用到了Convert類和System.Text命名空間下的類,Encoding是靜態(tài)類,ASCIIEncoding是實(shí)體類,方法都是一樣的!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Encoding
{
class Program
{
static void Main(string[] args)
{
var gb1 = System.Text.Encoding.GetEncoding("Unicode");
Console.WriteLine(gb1.GetString(gb1.GetBytes("測試")));

var gb0 = System.Text.Encoding.GetEncoding("UTF-8");
Console.WriteLine(gb0.GetString(gb0.GetBytes("測試")));

var gb = System.Text.Encoding.GetEncoding("GB2312");
Console.WriteLine(gb.GetString(gb.GetBytes("測試")));

#region 測試代碼

Console.WriteLine(IsChineseLetter("測試", 0));
Console.WriteLine(ChineseLetterCode("測試", 0));
Console.WriteLine(ChineseLetterFromCode(ChineseLetterCode("測試", 0)));

Console.WriteLine(gb1.GetString(
Utf8_2_Unicode(gb0.GetBytes("測試test"))));

//http://qkzz.net/article/3d697483-a5ae-4b50-9ae9-45dc6dd26141.htm
//http://topic.csdn.net/u/20090617/18/1907627e-ce38-4ae5-9755-1cc349a4ed1a.html
//一級漢字有 3755 個, 40 * 94=3760 個, 其中 d7fe, d7fd, d7fc, d7fb, d7fa 五位置為空
for (byte i = 0xb0; i < 0xd8; i++)
{
for (byte j = 0xa1; j < (i != 0xd7 ? 0xff : 0xfa); j++)
{
Console.Write(gb.GetString(new[] { i, j }));
if (j == 0xc7 || j == 0xee || j == (i != 0xd7 ? 0xfe : 0xf9))
Console.WriteLine();
}
}

Console.WriteLine(GetChineseLetterFromGb2312(0));
Console.WriteLine(GetChineseLetterFromGb2312(3754));

//漢字的 Unicode 編碼范圍
for (var i = 19968; i <= 40959; i++)
{
Console.Write(ChineseLetterFromCode(i));
}

#endregion

Console.Read();
}
public static string GetChineseLetterFromGb2312(int rNum)
{
if (rNum < 0 || rNum > 3754)
throw new ArgumentOutOfRangeException("rNum", "超出一級漢字的范圍!");
var gb = System.Text.Encoding.GetEncoding("GB2312");
return gb.GetString(new[] { (byte)(0xb0 + (rNum / 94)), (byte)(0xa1 + (rNum % 94)) });
}

/// <summary>
/// UTF8 漢字字節(jié)流轉(zhuǎn)成 Unicode 漢字字節(jié)流
/// </summary>
/// <param name="input"></param>
/// <see cref="http://hi.baidu.com/hyqsoft/blog/item/263795a164d1728346106464.html"/>
public static byte[] Utf8_2_Unicode(byte[] input)
{
var ret = new List<byte>();
for (var i = 0; i < input.Length; i++)
{
if (input[i] >= 240) // 11110xxx
{
//i += 3;
throw new Exception("四字節(jié)的 UTF-8 字符不能轉(zhuǎn)換成兩字節(jié)的 Unicode 字符!");
}
//else if (input[i] >= 224)
if (input[i] >= 224) // 1110xxxx
{
ret.Add((byte)((input[i + 2] & 63) | ((input[i + 1] & 3) << 6)));
ret.Add((byte)((input[i] << 4) | ((input[i + 1] & 60) >> 2)));
i += 2;
}
else if (input[i] >= 192) // 110xxxxx
{
ret.Add((byte)((input[i + 1] & 63) | ((input[i] & 3) << 6)));
ret.Add((byte)((input[i] & 28) >> 2));
i += 1;
}
else
{
ret.Add(input[i]);
ret.Add(0);
}
}
return ret.ToArray();
}

#region 漢字與Unicode編碼

public static bool IsChineseLetter(string input, int index)
{
var chfrom = Convert.ToInt32("4e00", 16); //范圍(0x4e00~0x9fff)轉(zhuǎn)換成int(chfrom~chend)
var chend = Convert.ToInt32("9fa5", 16);
if (input != "")
{
//var code = Char.ConvertToUtf32(input, index);
var gb = System.Text.Encoding.GetEncoding("Unicode");
var b = gb.GetBytes(input.Substring(index, 1));
var code = b[0] + b[1] * 0x100;

return code >= chfrom && code <= chend;
}
return false;
}

public static int ChineseLetterCode(string input, int index)
{
var chfrom = Convert.ToInt32("4e00", 16); //范圍(0x4e00~0x9fff)轉(zhuǎn)換成int(chfrom~chend)
var chend = Convert.ToInt32("9fa5", 16);
if (input != "")
{
var code = Char.ConvertToUtf32(input, index);

return code >= chfrom && code <= chend ? code : 0;
}
return 0;
}

public static string ChineseLetterHexCode(string input, int index)
{
var code = ChineseLetterCode(input, index);
return code != 0 ? code.ToString("X4") : string.Empty;
}

public static string ChineseLetterFromCode(int code)
{
var chfrom = Convert.ToInt32("4e00", 16); //范圍(0x4e00~0x9fff)轉(zhuǎn)換成int(chfrom~chend)
var chend = Convert.ToInt32("9fa5", 16);
//return code >= chfrom && code <= chend ? Char.ConvertFromUtf32(code) : string.Empty;
if (code >= chfrom && code <= chend)
{
var gb = System.Text.Encoding.GetEncoding("Unicode");
var b = new[] { (byte)(code % 0x100), (byte)(code / 0x100) };
return gb.GetString(b);
}
return string.Empty;
}

public static string ChineseLetterFromHexCode(string hexCode)
{
//var code = Convert.ToInt32(hexCode, 16);
var code = int.Parse(hexCode, NumberStyles.HexNumber);
return ChineseLetterFromCode(code);
}

#endregion

}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace QuotedPrintable解碼
{
class Program
{
static void Main(string[] args)
{
string init_str = "K度空間";
string encode_str = QuotedPrintable.Encode(init_str);
string decode_str = QuotedPrintable.Decode(encode_str);

Console.WriteLine(
"需要進(jìn)行QuotedPrintable編碼的原始字符串: " +
" {0} " +
"編碼后得到的字符串: " +
" {1} " +
"對編碼后得到的字符串進(jìn)行解碼得到的字符串: " +
" {2} ", init_str, encode_str, decode_str);
}

public class QuotedPrintable
{
/// <summary>
/// QuotedPrintable解碼函數(shù)
/// </summary>
/// <param name="input">需要解碼的QuotedPrintable字符串</param>
/// <returns>解碼后的字符串</returns>
public static string Decode(string input)
{
System.Text.Encoding encoding = System.Text.Encoding.GetEncoding("gb2312");

StringBuilder result = new StringBuilder();
StringReader sr = new StringReader(input);

string line = sr.ReadLine();

while( line!=null )
{
bool addCRLF = true;
byte[] bytes = System.Text.Encoding.ASCII.GetBytes( line.ToCharArray() );

for(int i=0;i<bytes.Length;i++)
{
if( ( bytes[i]>=33 && bytes[i]<=60 ) || ( bytes[i]>=62 && bytes[i]<=126 ) || bytes[i]==9 || bytes[i]==32)
{
result.Append( Convert.ToChar( bytes[i] ) );
continue;
}
else if( bytes[i]==61 )
{
if( i==bytes.Length-1 )
{
//eg. = soft line break;
addCRLF = false;
break;
}
else if( bytes[i+1]==51 && bytes[i+2]==68 )
{
//eg. =3D
i++;i++;
result.Append( "=" );
continue;
}
else
{
//eg. =B7=D6
byte[] b = new byte[2];
b[0] = Convert.ToByte( Convert.ToChar(bytes[i+1]).ToString()+Convert.ToChar(bytes[i+2]).ToString(),16 );
i++;i++;i++;
b[1] = Convert.ToByte( Convert.ToChar(bytes[i+1]).ToString()+Convert.ToChar(bytes[i+2]).ToString(),16 );
i++;i++;

result.Append(encoding.GetString(b));
continue;
}

}
}//end of for

line = sr.ReadLine();
if( line!=null && addCRLF )
result.Append(" ");
}//end of while
return result.ToString();
}

public static string Encode(string input)
{
System.Text.Encoding encoding = System.Text.Encoding.GetEncoding("gb2312");
const int MAXLINELENGTH = 76;
int currentLineLength = 0;
byte[] bytes = encoding.GetBytes(input.ToCharArray());
StringBuilder result = new StringBuilder();

for (int i = 0; i < bytes.Length; i++)
{
if (bytes[i] == 10 || bytes[i] == 13)
{
if (bytes[i] == 13 && GetNextByte(i, bytes, 1) == 10)
{
CheckLineLength(MAXLINELENGTH, ref currentLineLength, 0, result);
result.Append(" ");
currentLineLength = 0;
i++;
continue;
}

if (bytes[i] == 10)
{
CheckLineLength(MAXLINELENGTH, ref currentLineLength, 0, result);
result.Append(" ");
currentLineLength = 0;
}

if (bytes[i] == 13)
{
CheckLineLength(MAXLINELENGTH, ref currentLineLength, 3, result);
result.Append("=" + ConvertToHex(bytes[i]));
}
}
else
{
if ((bytes[i] >= 33 && bytes[i] <= 60) || (bytes[i] >= 62 && bytes[i] <= 126))
{
CheckLineLength(MAXLINELENGTH, ref currentLineLength, 1, result);
result.Append(System.Convert.ToChar(bytes[i]));
}
else
{
if (bytes[i] == 9 || bytes[i] == 32)
{
CheckLineLength(MAXLINELENGTH, ref currentLineLength, 0, result);
result.Append(System.Convert.ToChar(bytes[i]));
currentLineLength++;
}
else
{
CheckLineLength(MAXLINELENGTH, ref currentLineLength, 3, result);
result.Append("=" + ConvertToHex(bytes[i]));
}
}
}
}

return result.ToString();
}

private static void CheckLineLength(int maxLineLength, ref int currentLineLength, int newStringLength, StringBuilder sb)
{
if (currentLineLength + 1 == maxLineLength || currentLineLength + newStringLength + 1 >= maxLineLength)
{
sb.Append("= ");
currentLineLength = 0+newStringLength;
}
else
{
currentLineLength += newStringLength;
}
}

private static int GetNextByte(int index, byte[] bytes, int shiftValue)
{
int newIndex = index + shiftValue;

if (newIndex < 0 || newIndex > bytes.Length - 1 || bytes.Length == 0)
return -1;
else
return bytes[newIndex];
}

private static string ConvertToHex(byte number)
{
string result = System.Convert.ToString(number, 16).ToUpper();
return (result.Length == 2) ? result : "0" + result;
}

}

}
}

SQL基礎(chǔ)知識

總結(jié)

以上是生活随笔為你收集整理的编码解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。