不同字符编码格式之间的转换
来源:互联网 发布:天谕萝莉捏脸数据 编辑:程序博客网 时间:2024/06/09 14:31
一、概述
为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。
二、编码格式分类
1、ansi编码
不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码 代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。
对于ANSI编码而言,0x00~0x7F之间的字符,依旧是1个字节代表1个字符。这一点是ASNI编码与Unicode编码之间最大也最明显的区别。比如“A君是第131号”,在ANSI编码中,占用12个字节,而在Unicode编码中,占用16个字节。因为A和1、3、1这4个字符,在ANSI编码中只各占1个字节,而在Unicode编码中,是需要各占2个字节的。
2、cp936编码
cp936是微软自己发布的用在文件系统中的编码方式。而bg2312是中国国家标准。
目前Windows的内核已经采用Unicode编码,这样在内核上可以支持全世界所有的语言文字。但是由于现有的大量程序和文档都采用了某种特定语言的编码,例如GBK,Windows不可能不支持现有的编码,而全部改用Unicode。Windows 使用代码页(code page)来适应各个国家和地区。code page可以被理解为前面提到的内码。GBK对应的code page是 CP936。
3、GB2312编码 GB2312(1980年)一共收录了7445个字符,包括6763个汉字和 682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。
ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。
2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。
4、Unicode编码
Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。 Unicode的学名是 "Universal Multiple-Octet Coded Character Set",简称为UCS。 UCS可以看作是"Unicode Character Set"的缩写。
UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UTF-8的一个特别的好处是它与ISO- 8859-1完全兼容。UTF是 “UCS Transformat ion Format”的缩写。
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。
UTF-8:UTF意为通用字集转换格式(Universal Character Set Transformation Format),UTF-8是Unicode的8位元格式。如果使用只能在同类位元组内支持8个位元的重要资料一类的旧式传输媒体,可选择UTF-8格式。
Unicode规范中推荐的标记字节顺序的方法是BOM。
在UCS编码中有一个叫做"ZERO WIDTH NO- BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO- BREAK SPACE"又被称作BOM。UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
Windows就是使用BOM来标记文本文件的编码方式的。
ANSI: 无格式定义; Unicode: 前两个字节为FFFE; Unicode big endian: 前两字节为FEFF; UTF-8: 前两字节为EFBB;
三、实例应用
im中在线课程搜索功能(双字节转换成单字节)
//zhang20120228 在线课程的搜索功能,将unicode转换为utf8void CSearchWndHC::UrlEncodeUtf8(LPCTSTR pszUrl, LPTSTR pResult, long * plLen){// TODO: Add your specialized code here.if(pszUrl == NULL){//*pResult = 0;*plLen = 0;return ;}int iLen = lstrlen(pszUrl);if (pResult == 0) {*plLen = 0;return;}pResult[0]=0;int i = 0;BYTE j,k;BYTE* p=(BYTE* )pszUrl;while(*p){if((*p <=_T('9') && *p >=_T('0'))||(*p <=_T('z') && *p >=_T('a'))||(*p<=_T('Z') && *p >=_T('A'))){pResult[i++]=*p++;}else{if(*p <0 ||*p >127){j= *p/16;k=*p%16;if(j > 9) j+=_T('A')-10;else j+=48;if(k > 9) k+=_T('A')-10;else k+=48;pResult[i++]=_T('%');pResult[i++]=j;pResult[i++]=k;p++;j= *p/16;k=*p%16;if(j > 9) j+=_T('A')-10;else j+=48;if(k > 9) k+=_T('A')-10;else k+=48;pResult[i++]=_T('%');pResult[i++]=j;pResult[i++]=k;p++;}else {j= *p/16;k=*p%16;if(j > 9) j+=_T('A')-10;else j+=48;if(k > 9) k+=_T('A')-10;else k+=48;pResult[i++]=_T('%');pResult[i++]=j;pResult[i++]=k;p++;}}}pResult[i]=0;*plLen = i;//*ppResult = pResult;}//zhang20120228 在线课程的搜索功能,将unicode转换为utf8LPTSTR CSearchWndHC::translateTCHARToUTF_8(LPTSTR xmlStream, int len) {HRESULT hr;IMultiLanguage *pMultiLanguage=NULL;UINT one=0;UINT two=0;DWORD pdwMode=0;LPTSTR m_setstr=NULL;LPTSTR m_getstr=NULL;LPTSTR finalTCHARBuffer=NULL ;CoInitialize(NULL);hr=CoCreateInstance(CLSID_CMultiLanguage,NULL,CLSCTX_ALL,IID_IMultiLanguage ,(void**)&pMultiLanguage);if( FAILED(hr)){return 0;}one=len;m_setstr=(LPTSTR )xmlStream;hr=pMultiLanguage->ConvertString(&pdwMode,COVS_0001,COVS_0030,(unsigned char*)m_setstr,&one,NULL,&two);//hr=pMultiLanguage->ConvertString(&pdwMode,20936,65001,(unsigned char*)m_setstr,&one,NULL,&two);if( FAILED(hr)){pMultiLanguage->Release();CoUninitialize();delete[] m_getstr;return 0; }m_getstr=new TCHAR[two + 1];memset( m_getstr, _T('\0'), two + 1 );//hr=pMultiLanguage->ConvertString(&pdwMode,20936,65001,(unsigned char*)m_setstr,&one,(unsigned char*)m_getstr,&two);hr=pMultiLanguage->ConvertString(&pdwMode,COVS_0001,COVS_0030,(unsigned char*)m_setstr,&one,(unsigned char*)m_getstr,&two);if( FAILED(hr)){pMultiLanguage->Release();CoUninitialize();delete[] m_getstr;return 0; }pMultiLanguage->Release();CoUninitialize();finalTCHARBuffer = new TCHAR[two+1];memset(finalTCHARBuffer,0,sizeof(finalTCHARBuffer));memcpy(finalTCHARBuffer,m_getstr,two+1);delete[] m_getstr; return finalTCHARBuffer;pMultiLanguage->Release();CoUninitialize();delete[] m_getstr;return 0;}
urlencode函数
数学 --》 %CA%FD%D1%A7
//zhang20110804 新添加一个函数,赋值拼http地址串CString CSearchWndHC::URLEncode(CString sIn){CString sOut;const int nLen = sIn.GetLength() + 1;register LPBYTE pOutTmp = NULL;LPBYTE pOutBuf = NULL;register LPBYTE pInTmp = NULL;LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);BYTE b = 0;//alloc out bufferpOutBuf = (LPBYTE)sOut.GetBuffer(nLen*3 - 2);//new BYTE [nLen * 3];if(pOutBuf){pInTmp = pInBuf;pOutTmp = pOutBuf;// do encodingwhile (*pInTmp){if(isalnum(*pInTmp))*pOutTmp++ = *pInTmp;elseif(isspace(*pInTmp))*pOutTmp++ = '+';else{*pOutTmp++ = '%';*pOutTmp++ = toHex(*pInTmp>>4);*pOutTmp++ = toHex(*pInTmp%16);}pInTmp++;}*pOutTmp = '\0';//sOut=pOutBuf;//delete [] pOutBuf;sOut.ReleaseBuffer();}sIn.ReleaseBuffer();return sOut;}
linux urlEncodeGb2312
数学 --》 %CA%FD%D1%A7
#include <stdio.h>#include <IOSTREAM>using namespace std;typedef unsigned char BYTE; BYTE toHex(const BYTE &x) { return x > 9 ? x -10 + 'A': x + '0'; } BYTE fromHex(const BYTE &x) { return isdigit(x) ? x-'0' : x-'A'+10; } string URLEncode(const string &sIn) { string sOut; for( size_t ix = 0; ix < sIn.size(); ix++ ) { BYTE buf[4]; memset( buf, 0, 4 ); if( isalnum( (BYTE)sIn[ix] ) ) { buf[0] = sIn[ix]; } //else if ( isspace( (BYTE)sIn[ix] ) ) //貌似把空格编码成%20或者+都可以 //{ // buf[0] = '+'; //} else { buf[0] = '%'; buf[1] = toHex( (BYTE)sIn[ix] >> 4 ); buf[2] = toHex( (BYTE)sIn[ix] % 16); } sOut += (char *)buf; } return sOut; }string URLDecode(const string &sIn) { string sOut; for( size_t ix = 0; ix < sIn.size(); ix++ ) { BYTE ch = 0; if(sIn[ix]=='%') { ch = (fromHex(sIn[ix+1])<<4); ch |= fromHex(sIn[ix+2]); ix += 2; } else if(sIn[ix] == '+') { ch = ' '; } else { ch = sIn[ix]; } sOut += (char)ch; } return sOut; } int main(int argc, char* argv[]){printf("Hello World!\n");string str = "数学zhang";string out = URLEncode(str);string instr = URLDecode(out);cout<<out.c_str()<<endl;cout<<instr.c_str()<<endl;return 0;}
- 不同字符编码格式之间的转换
- 字符编码之间的转换
- 字符编码之间的转换
- 不同字符集之间的编码转换
- 不同进制、编码之间的转换
- 字符编码格式转换
- VC++字符编码之间的转换
- VC++字符编码之间的转换
- 包含 java dom4j document和String之间的转换 数据流的发送 字符编码格式的转换
- Python的时间字符串,不同格式,时间戳之间转换
- 字符编码Unicode UTF-8 GBK的不同和转换
- 字符的编码格式
- 多种国际编码格式之间进行文本内码的转换
- C#通过编码在字符和字节之间的转换
- UTF8与GBK字符编码之间的相互转换
- UTF8与GBK字符编码之间的相互转换
- UTF8与GBK字符编码之间的相互转换
- 编码之间的转换
- QT——基于Qt多媒体技术和编码技术的本地音视频远程传输
- 【网络模型】IO复用
- SAX方式进行XML解析
- ios之wkwebview与UIwebview的对比
- c中指针数组
- 不同字符编码格式之间的转换
- Java多线程 -- ConcurrentHashMap
- Android UI 优化——使用HierarchyViewer工具
- stl min_element和max_element
- Android WebView 开发详解(三)
- Swift中返回字符串的宽度
- 程序员之所以犯错误,不是因为他们不懂,而是因为他们自以为什么都懂。
- spring MVC 配置文件解析
- Android™ 2.1 android.R.drawable Icon Resources