关于各种编码总结

关于各种编码总结

一、背景知识

1、计算机中所有的数据都用01串来表示,至于一串01到底代表什么是由软件来设定的。

比如:01111101111101010111110111110101可以理解为一条指令,也可以理解为4个字节的char字符,具体是什么要看这个数据是在代码段还是数据段。

2、字符是人看到的显示效果(实际上人看到的是字符对应glyph渲染到屏幕上的效果)

3、字符有内部的存储格式(如'中'在内存中存为d6d0(gb2312编码)),这种编码叫内码,本质上是将人理解的字符,映射为二进制01串

4、字符需要在系统间交换,这时同样是'中'在简体中文版OS和繁体中文版OS中内部表示的格式不同,为了进行数据交换,需要能够标记一个字符,这种编码叫交换码,典型的如unicode、CNS11643、CCCII

5、windowsNT一个字符显示的过程:读入内码---转为unicode(widechar)---找到字体中对应的字模(glyph)---将此glyph(位图)写到显存---调用显卡刷到显示器上

二、基本概念

1、计算机一开始是在英语国家中产生的,所以计算机的系统一开始都会做一件事:对拉丁字母进行编码,加上一些控制符号、数学符号等,这便形成了ASCII编码。

2、像英语这样的拼音文字很容易编码,因为所有的词是由26个字母组合而成的,只要编码26个字母,就可以输入所有的单词。但是像中文这样的象形文字,则只能针对每个字分别进行编码(因为每个字的字形都不一样),这样旧有的编码是没法满足中国人的要求的(你总不能要求只有懂英语的人才能用电脑吧!),所以老一代的中国程序员就要为中文进行编码,其中典型的代表是gb2312(简体)、big5(繁体),所谓的编码就是确定中文的每个字在内存中对应的01串是什么,比如'国'在内存中用b9fa(gb2312编码)表示。

3、因为每个国家的文字是不同的,编码的方式也是不同的,比如b9fa在大陆代表'国',在日本就代表特定的日语字符了,那么怎么样进行信息交换呢?比如我在中国写了一份源代码,现在要拿到日本编译,那么不好意思,编译不了,因为这里的语义已经改变了。为了能够进行信息的交换,最简单的办法就是为全世界所有的语言的所有的字符都指定一个唯一的编码,这个就是unicode编码

4、unicode是统一标记,但是unicode有很多种内部存储的格式,比如unicode为4e2d的字符在内存中可以用3、4或5个字节来表示,这种内部存储的表示形式叫内码,典型的实现有utf-8(unix标准)、utf-16(windows标准)、utf-32等

5、在简体中文windows下使用文本编辑器创建的文本文件,使用的编码方式是gb2312,即编码方式是根据locale确定的默认的编码方式。如果需要和类unix系统下的人进行协作开发时就要注意将编码方式改为utf-8

三、编码转换

2种内码进行转换,需要有个媒介------unicode,一个转换编码的例子:(windows平台)uft8(multibyte)------unicode(wideChar)-----gb2312(multibyte)

intUTF8ToGB(constchar*str,char*out)

{

WCHAR*strSrc;

TCHAR*szRes;

intlen;

//获得临时变量的大小

//后4个参数是输入的指针,长度,输出的指针,长度,这里第4个参数是-1,返回unicode字符数

inti=MultiByteToWideChar(CP_UTF8,0,str,-1,NULL,0);

strSrc=newWCHAR[i+1];//unicode字符数组

MultiByteToWideChar(CP_UTF8,0,str,-1,strSrc,i);

//获得临时变量的大小

i=WideCharToMultiByte(CP_ACP,0,strSrc,-1,NULL,0,NULL,NULL);

szRes=newTCHAR[i+1];//内码字符的长度

WideCharToMultiByte(CP_ACP,0,strSrc,-1,szRes,i,NULL,NULL);

len=(i+1)*sizeof(CHAR);

memcpy(out,szRes,len);

out[len+1]='\0';

delete[]strSrc;

delete[]szRes;

returnlen;

}

四、编程语言的支持

1、javajava内置对unicode的支持,即newString(...)时,使用的是unicode编码格式,所有字符串的操作也是针对unicode,要返回指定编码的字节数组使用getBytes

例子:

2、c、c++

charVSwcharstringVSwstring

例子:vc2005测试

//testString.cpp:Definestheentrypointfortheconsoleapplication.

//

#include"stdafx.h"

#include<cstring>

#include<iostream>

#include<string>

#include<locale>

intmain(intargc,char*argv[])

{

constchartext[]="中\u534e人民共和国,龢籦";//这个里面存的是字符串的gb2312内码,但是可以用\u(unicode)来指定字符

constwchar_twtext[]=L"中\u534e人民共和国,龢籦";//这个里面存的是unicode

std::strings1("中\u534e人民共和国,龢籦");

std::wstrings2(L"中\u534e人民共和国,龢籦");

std::cout<<"sizeof(char):"<<sizeof(char)<<std::endl;

std::cout<<"text:"<<text<<std::endl;

std::cout<<"sizeof(text):"<<sizeof(text)<<std::endl;//算的是字节的数量

std::cout<<"strlen(text):"<<strlen(text)<<std::endl;

std::cout<<"text(binary):";

for(size_ti=0,iMax=strlen(text);i<iMax;++i)

{

std::cout<<""<<std::hex<<static_cast<unsignedint>(static_cast<unsignedchar>(text[i]));

}

std::cout<<std::endl<<std::endl;

std::cout<<"sizeof(wchar_t):"<<sizeof(wchar_t)<<std::endl;

std::cout<<"wtext:"<<wtext<<std::endl;

std::cout<<"wtext:UNABLETOCONVERTNATIVELY."<<std::endl;

std::cout<<"sizeof(wtext):"<<sizeof(wtext)<<std::endl;

std::cout<<"wcslen(wtext):"<<wcslen(wtext)<<std::endl;//这个函数可以正确的返回字符的个数

std::cout<<"wtext(binary):";

for(size_ti=0,iMax=wcslen(wtext);i<iMax;++i)

{

std::cout<<""<<std::hex<<static_cast<unsignedint>(static_cast<unsignedshort>(wtext[i]));

}

std::cout<<std::endl<<std::endl;

std::cout<<"sizeof(s1):"<<s1.length()<<std::endl;

std::cout<<"s1:"<<s1<<std::endl;

std::cout<<"s1(binary):";

constchar*temp=s1.c_str();

for(size_ti=0;i<s1.length();++i)

{

std::cout<<""<<std::hex<<static_cast<unsignedint>(static_cast<unsignedshort>(temp[i]));//二进制的数据与char的类似,只是每个的前面都加上了ff

}

std::cout<<std::endl<<std::endl;

std::localeloc("chs");

std::wcout.imbue(loc);//设定本地的编码

std::wcout<<L"中国"<<std::endl;

std::wcout<<"sizeof(s2):"<<s2.length()<<std::endl;

std::wcout<<"s2:"<<s2<<std::endl;

std::wcout<<"s2(binary):";

constwchar_t*temp1=s2.c_str();

for(size_ti=0;i<s2.length();++i)

{

std::wcout<<""<<std::hex<<static_cast<unsignedint>(static_cast<unsignedshort>(temp1[i]));//这个和上面的unicode的数据是一致的

}

return0;

}

输出:

sizeof(char):1

text:中华人民共和国,龢籦

sizeof(text):21

strlen(text):20

text(binary):d6d0bbaac8cbc3f1b9b2bacdb9faa3acfd98bb62

sizeof(wchar_t):2

wtext:0013FF1C

wtext:UNABLETOCONVERTNATIVELY.

sizeof(wtext):16

wcslen(wtext):a

wtext(binary):4e2d534e4eba6c115171548c56fdff0c9fa27c66

sizeof(s1):14

s1:中华人民共和国,龢籦

s1(binary):ffd6ffd0ffbbffaaffc8ffcbffc3fff1ffb9ffb2ffbaffcdffb9

fffaffa3ffacfffdff98ffbb62

中国

sizeof(s2):10

s2:中华人民共和国,龢籦

s2(binary):4,e2d5,34e4,eba6,c115,1715,48c5,6fdf,f0c9,fa27,c66

五其他

Unicode编码表到GB2312编码表映射表

相关推荐