当前位置: 技术问答>linux和unix
求字符集编码转换的源码
来源: 互联网 发布时间:2015-09-02
本文导语: 基本类似iconv的功能,降输入的内容,转换成另一种编码格式. 我down了iconv的源码,太复杂了. 有没有简单些的,哪怕是只实现了1种转换方法源码可以参考. 3q ps:现在对转码的原理也是一头雾水(我理解:是通过在两张码表...
基本类似iconv的功能,降输入的内容,转换成另一种编码格式.
我down了iconv的源码,太复杂了.
有没有简单些的,哪怕是只实现了1种转换方法源码可以参考.
3q
ps:现在对转码的原理也是一头雾水(我理解:是通过在两张码表中的两次定位吧)
有这方面的网站推荐也好阿
我down了iconv的源码,太复杂了.
有没有简单些的,哪怕是只实现了1种转换方法源码可以参考.
3q
ps:现在对转码的原理也是一头雾水(我理解:是通过在两张码表中的两次定位吧)
有这方面的网站推荐也好阿
|
国际标准 ISO 10646 定义了 通用字符集 (Universal Character Set, UCS). UCS 是所有其他字符集标准的一个超集.
历史上, 有两个独立的, 创立单一字符集的尝试. 一个是国际标准化组织(ISO)的 ISO 10646 项目, 另一个是由(一开始大多是美国的)多语言软件制造商组成的协会组织的 Unicode 项目. 幸运的是, 1991年前后, 两个项目的参与者都认识到, 世界不需要两个不同的单一字符集. 它们合并双方的工作成果, 并为创立一个单一编码表而协同工作. 两个项目仍都存在并独立地公布各自的标准, 但 Unicode 协会和 ISO/IEC JTC1/SC2 都同意保持 Unicode 和 ISO 10646 标准的码表兼容, 并紧密地共同调整任何未来的扩展.
首先 UCS 和 Unicode 只是分配整数给字符的编码表. 现在存在好几种将一串字符表示为一串字节的方法. 最显而易见的两种方法是将 Unicode 文本存储为 2 个 或 4 个字节序列的串. 这两种方法的正式名称分别为 UCS-2 和 UCS-4. 除非另外指定, 否则大多数的字节都是这样的(Bigendian convention). 将一个 ASCII 或 Latin-1 的文件转换成 UCS-2 只需简单地在每个 ASCII 字节前插入 0x00. 如果要转换成 UCS-4, 则必须在每个 ASCII 字节前插入三个 0x00.
在 Unix 下使用 UCS-2 (或 UCS-4) 会导致非常严重的问题. 用这些编码的字符串会包含一些特殊的字符, 比如 '' 或 '/', 它们在 文件名和其他 C 库函数参数里都有特别的含义. 另外, 大多数使用 ASCII 文件的 UNIX 下的工具, 如果不进行重大修改是无法读取 16 位的字符的. 基于这些原因, 在文件名, 文本文件, 环境变量等地方, UCS-2 不适合作为 Unicode 的外部编码.!!!注意外部编码的概念
在 ISO 10646-1 Annex R 和 RFC 2279 里定义的 UTF-8 编码没有这些问题. 它是在 Unix 风格的操作系统下使用 Unicode 的明显的方法.
下面是我写的一个简单的显示unicode->utf-8的转换方法的小程序:
#include
#include
using std::cout;
using std::cin;
/*
name:
argumens:
return:number of string changed
*/
int getutfchar(unsigned int n, char* s){
/*
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
static const int __character_offset[] = {7,11,16,21,26,31};
static const int __type_prefix[] = {0x00,0xc0,0xe0,0xf0,0xfa,0xfc};
int type;
for(type = 0; n >> __character_offset[type] && type 0 ; --i){
int r = n - ((n >> 6) = 6;
s[i] = 0x80 | r;
}
s[0] = __type_prefix[type] | n;
return type + 1;
}
int main(){
char utfchar[6]="ERROR";
unsigned int utfnum;
do{
cout std::hex >> utfnum;
utfchar[getutfchar(utfnum,utfchar)] = 0;
cout
历史上, 有两个独立的, 创立单一字符集的尝试. 一个是国际标准化组织(ISO)的 ISO 10646 项目, 另一个是由(一开始大多是美国的)多语言软件制造商组成的协会组织的 Unicode 项目. 幸运的是, 1991年前后, 两个项目的参与者都认识到, 世界不需要两个不同的单一字符集. 它们合并双方的工作成果, 并为创立一个单一编码表而协同工作. 两个项目仍都存在并独立地公布各自的标准, 但 Unicode 协会和 ISO/IEC JTC1/SC2 都同意保持 Unicode 和 ISO 10646 标准的码表兼容, 并紧密地共同调整任何未来的扩展.
首先 UCS 和 Unicode 只是分配整数给字符的编码表. 现在存在好几种将一串字符表示为一串字节的方法. 最显而易见的两种方法是将 Unicode 文本存储为 2 个 或 4 个字节序列的串. 这两种方法的正式名称分别为 UCS-2 和 UCS-4. 除非另外指定, 否则大多数的字节都是这样的(Bigendian convention). 将一个 ASCII 或 Latin-1 的文件转换成 UCS-2 只需简单地在每个 ASCII 字节前插入 0x00. 如果要转换成 UCS-4, 则必须在每个 ASCII 字节前插入三个 0x00.
在 Unix 下使用 UCS-2 (或 UCS-4) 会导致非常严重的问题. 用这些编码的字符串会包含一些特殊的字符, 比如 '' 或 '/', 它们在 文件名和其他 C 库函数参数里都有特别的含义. 另外, 大多数使用 ASCII 文件的 UNIX 下的工具, 如果不进行重大修改是无法读取 16 位的字符的. 基于这些原因, 在文件名, 文本文件, 环境变量等地方, UCS-2 不适合作为 Unicode 的外部编码.!!!注意外部编码的概念
在 ISO 10646-1 Annex R 和 RFC 2279 里定义的 UTF-8 编码没有这些问题. 它是在 Unix 风格的操作系统下使用 Unicode 的明显的方法.
下面是我写的一个简单的显示unicode->utf-8的转换方法的小程序:
#include
#include
using std::cout;
using std::cin;
/*
name:
argumens:
return:number of string changed
*/
int getutfchar(unsigned int n, char* s){
/*
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
static const int __character_offset[] = {7,11,16,21,26,31};
static const int __type_prefix[] = {0x00,0xc0,0xe0,0xf0,0xfa,0xfc};
int type;
for(type = 0; n >> __character_offset[type] && type 0 ; --i){
int r = n - ((n >> 6) = 6;
s[i] = 0x80 | r;
}
s[0] = __type_prefix[type] | n;
return type + 1;
}
int main(){
char utfchar[6]="ERROR";
unsigned int utfnum;
do{
cout std::hex >> utfnum;
utfchar[getutfchar(utfnum,utfchar)] = 0;
cout