1. Code Page 历史发展
此技术的使用最早追溯到 MS-DOS3.3(1987 年 4 月发行)向 IBMPC 用户引进了内码表的概念,Windows 也使用此概念。
最初的 IBM 字元集被称作内码表 437,或者(MS-DOSLatinUS)。内码表 850 就是「MS-DOSLatin1」,它用附加的带重音字母(但不是 Latin1ISO/ANSI 标准)代替了一些线形字符。
在 MS-DOS 中,如果用户为 PC 的键盘、显示卡和打印机指定了一个内码表,然后在 PC 上创建、编辑和打印文件,一切都很正常,每件事都会保持一致。然而,如果用户试图与使用不同内码表的用户交换文件,或者在机器上改变内码表,就会产生字符码与错误的字符相关联问题。应用程序能够将内码表信息与文件一起保存来试图减少问题的产生,但该策略包括了某些在内码表间转换的工作。
虽然内码表最初仅提供了不包括带重音符号字母的附加拉丁字符集,但最终内码表的较高的 128 个字符还是包括了完整的非拉丁字母,例如希伯来语、希腊语和斯拉夫语。自然,如此多样会导致内码表变得混乱。如果少数带重音的字母未正确显示,那么字符便会混乱不堪而不可阅读。
内码表的扩展正是基于所有这些原因,但是还不够。最低的 128 个代码总是相同的,较高的 128 个代码取决于定义内码表的语言。其他内码表被其他语言定义,每个环境下的内码表都是对该环境所作的标准字符集修正。
字符内码 (character code)
字符内码 (character code) 指的是用来代表字符的内码。在输入和存储文档时都要使用内码,内码分为单字节内码和双字节内码。
单字节内码 – Single-Byte character sets (SBCS), 可以支持 256 个字符编码。
双字节内码 – Double-Byte character sets) (DBCS), 可以支持 65000 个字符编码,主要用来对大字符集的东方文字进行编码。
Code Page
Code Page 是一个经过挑选的以特定顺序排列的字符内码列表(内码表)。
对于早期的单字节内码的语种,Code Page 中的内码顺序使得系统可以按照此列表来根据键盘的输入值给出一个对应的内码。
对于双字节内码,则给出的是 MultiByte 到 Unicode 的对应表,这样就可以把以 Unicode 形式存放的字符转化为相应的字符内码。
在 1980 年前,仍然没有任何国际标准如 ISO-8859 或 Unicode 来定义如何扩展 US-ASCII 编码以便非英语国家的用户使用。很多 IT 厂商发明了他们自己的编码,并且使用了难以记忆的数目来标识。
1.1 CJK
同 Extended Unix Coding ( EUC ) 编码大不一样的是,下面所有的远东 Code Page 都利用了 C1 控制码(=80…=9F)做为首字节,使用 ASCII 值(=40…=7E)做为第二字节,这样才能包含多达数万个双字节字符,这表明在这种编码之中小于 3F 的 ASCII 值不一定代表 ASCII 字符。
C1 控制码范围(=80…=9F):用作远东编码中的首字节,不同于传统的 ASCII 字符。
ASCII 值范围(=40…=7E):被用作远东编码的第二字节。
小于 3F 的 ASCII 值指的是 ASCII 编码中十进制数值小于63(十六进制表示为 3F )的字符。
该设计使得这些编码能够支持更多字符,包括汉字等双字节字符,以确保能够在远东地区的编码系统中有效地表示和处理大量的字符集,远远超出了传统 ASCII 字符集的限制。
CP932
Shift-JIS 包含日本语 charset JIS X 0201 (每个字符一个字节) 和 JIS X 0208 (每个字符两个字节),所以 JIS X 0201 平假名包含一个字节半宽的字符,其剩馀的 60 个字节被用做 7076 个汉字以及 648 个其他全宽字符的首字节。同 EUC-JP 编码区别的是,Shift-JIS 没有包含 JIS X 202 中定义的 5802 个汉字。
Shift_JIS 是一个日本电脑系统常用的编码表。在微软及 IBM 的日语电脑系统中,使用了该编码表,称为 CP932。
它能容纳全角及半角拉丁字母、平假名、片假名、符号及日语汉字。
它被命名为 Shift_JIS 的原因,是它在放置全角字符时,要避开原本在 0xA1-0xDF 放置的半角假名字符。
CP936
GBK 扩展了 EUC-CN 编码 ( GB 2312-80 编码,包含 6763 个汉字) 到 Unicode (GB13000.1-93) 中定义的 20902 个汉字,中国大陆使用的是简体中文 zh_CN。
EUC-CN 是 GB2312 最常用的表示方法。浏览器编码表上的 “GB2312”,通常都是指 “EUC-CN” 表示法。
GB 2312 字元使用两个字节来表示。
“第一位字节” 使用 0xB0-0xF7
“第二位字节” 使用 0xA1-0xFE
举例来说,“啊” 字是 GB 2312 之中的第一个汉字,它的区位码是 1601。
在 EUC-CN 之中,它把 0xA0+16=0xB0,0xA0+1=0xA1,得出 0xB0A1。
CP949
UnifiedHangul (UHC) 是韩文 EUC-KR 编码 (KS C 5601-1992 编码,包括 2350 韩文音节和 4888 个汉字 a) 的超集,包含 8822 个附加的韩文音节 ( 在 C1 中 )。
EUC-KR 用来储存韩国 KSX1001 字集 (旧称 KSC5601) 的字符。此规格由 KSX2901 (旧称 KS C 5861) 定义。
KS X 1001 字元使用两个字节来表示。
“高位字节” 使用 0xA1-0xFE
“低位字节” 使用 0xA1-0xFE
CP950
代替 EUC-TW (CNS 11643-1992) 的 Big5 编码 (13072 繁体 zh_TW 中文字) 繁体中文,这些定义都在 Ken Lunde 的 CJK.INF 中或者 Unicode 编码表中找到。
EUC-TW 本来是台湾使用的其中一个汉字储存方法,以 CNS11643 字表为基础。但是台湾普遍使用大五码,EUC-TW 甚少使用。
CNS 11643 第一字面的字元使用两个字节来表示。
“第一位字节” 使用 0xA1-0xFE
“第二位字节” 使用 0xA1-0xFE
CNS 11643 其他字面的字元使用四个字节来表示(CNS 11643 第一字面可选择使用两个字节或四个字节来表示)。
“第一位字节” 使用 0x8E
“第二位字节” 使用 0xA1-0xB0 (0xA1-0xA7 分别代表第 1 至第 7 个字面,其余未定义)
“第三位字节” 使用 0xA1-0xFE
“第四位字节” 使用 0xA1-0xFE
Microsoft 采用了以上四种 Code Page,因此在访问Microsoft的文件系统时,需要根据文件中包含的具体语言文本选择适合的 Code Page,以确保文本能够正确地显示和处理。
1.2 IBM 的远东语言 Codepage
IBM 的 Codepage 分为 SBCS 和 DBCS 两种
IBM SBCS Codepage
37 (英文) *
290 (日文) *
833 (韩文) *
836 (简体中文) *
891 (韩文)
897 (日文)
903 (简体中文)
904 (繁体中文)
IBM DBCS Codepage
300 (日文) *
301 (日文)
834 (韩文) *
835 (繁体中文) *
837 (简体中文) *
926 (韩文)
927 (繁体中文)
928 (简体中文)
将 SBCS 的 Codepage 和 DBCS 的 Codepage 混合起来就成为: IBM MBCS Codepage
930 (日文) (Codepage 300 加 290) *
932 (日文) (Codepage 301 加 897)
933 (韩文) (Codepage 834 加 833) *
934 (韩文) (Codepage 926 加 891)
938 (繁体中文) (Codepage 927 加 904)
936 (简体中文) (Codepage 928 加 903)
5031 (简体中文) (Codepage 837 加 836) *
5033 (繁体中文) (Codepage 835 加 37) *
EBCDIC (Extended Binary Coded Decimal Interchange Code) 为国际商用机器公司 (IBM) 于 1963 年 - 64 年间推出的字符编码表,根据早期打孔机式的二进制编码的十进制数 (BCD, Binary Coded Decimal) 排列而成。
* 代表采用 EBCDIC 编码格式。IBM OS/2 支持多种 EBCDIC 内码表。
由此可见,Mircosoft 的 CJK Codepage 来源于 IBM 的 Codepage。
2. Linux 下 Codepage 的作用
在 Linux 下引入对 Codepage 的支持主要是为了访问 FAT/VFAT/FAT32/NTFS/NCPFS 等文件系统下的多语种文件名的问题。
目前,在 NTFS 和 FAT32/VFAT 下的文件系统上都使用了 Unicode,需要系统在读取这些文件名时动态将其转换为相应的语言编码,因此引入了 NLS(National Language Support)支持。
其相应的程序文件在 /usr/src/linux/fs/nls
下:
Config.in
Makefile
nls_base.c
nls_cp437.c
nls_cp737.c
nls_cp775.c
nls_cp850.c
nls_cp852.c
nls_cp855.c
nls_cp857.c
nls_cp860.c
nls_cp861.c
nls_cp862.c
nls_cp863.c
nls_cp864.c
nls_cp865.c
nls_cp866.c
nls_cp869.c
nls_cp874.c
nls_cp936.c
nls_cp950.c
nls_iso8859-1.c
nls_iso8859-15.c
nls_iso8859-2.c
nls_iso8859-3.c
nls_iso8859-4.c
nls_iso8859-5.c
nls_iso8859-6.c
nls_iso8859-7.c
nls_iso8859-8.c
nls_iso8859-9.c
nls_koi8-r.c
实现了下列函数:
extern int utf8_mbtowc (__u16 *, const __u8 *, int);
extern int utf8_mbstowcs (__u16 *, const __u8 *, int);
extern int utf8_wctomb (__u8 *, __u16, int);
extern int utf8_wcstombs (__u8 *, const __u16 *, int);
在加载相应的文件系统时就可以用下面的参数来设置 Codepage:
对于 Codepage 437 来说
mount -t vfat /dev/hda1 /mnt/1 -o codepage=437,iocharset=cp437
在 Linux 下就可以正常访问不同语种的长文件名了。
3. Linux 下支持的 Codepage
nls codepage 437 – 美国 / 加拿大英语
nls codepage 737 – 希腊语
nls codepage 775 – 波罗的海语
nls codepage 850 – 包括西欧语种 (德语,西班牙语,意大利语) 中的一些字符
nls codepage 852 – Latin 2 包括中东欧语种 (阿尔巴尼亚语,克罗地亚语,捷克语,英语,芬兰语,匈牙利语,爱尔兰语,德语,波兰语,罗马利亚语,塞尔维亚语,斯洛伐克语,斯洛文尼亚语,Sorbian 语)
nls codepage 855 – 斯拉夫语
nls codepage 857 – 土耳其语
nls codepage 860 – 葡萄牙语
nls codepage 861 – 冰岛语
nls codepage 862 – 希伯来语
nls codepage 863 – 加拿大语
nls codepage 864 – 阿拉伯语
nls codepage 865 – 日尔曼语系
nls codepage 866 – 斯拉夫语 / 俄语
nls codepage 869 – 希腊语 (2)
nls codepage 874 – 泰语
nls codepage 936 – 简体中文 GBK
nls codepage 950 – 繁体中文 Big5
nls iso8859-1 – 西欧语系 (阿尔巴尼亚语,西班牙加泰罗尼亚语,丹麦语,荷兰语,英语,Faeroese 语,芬兰语,法语,德语,加里西亚语,爱尔兰语,冰岛语,意大利语,挪威语,葡萄牙语,瑞士语.) 这同时适用于美国英语.
nls iso8859-2 – Latin 2 字符集,斯拉夫 / 中欧语系 (捷克语,德语,匈牙利语,波兰语,罗马尼亚语,克罗地亚语,斯洛伐克语,斯洛文尼亚语)
nls iso8859-3 – Latin 3 字符集,(世界语,加里西亚语,马耳他语,土耳其语)
nls iso8859-4 – Latin 4 字符集,(爱莎尼亚语,拉脱维亚语,立陶宛语), 是 Latin 6 字符集的前序标准
nls iso8859-5 – 斯拉夫语系 (保加利亚语,Byelorussian 语,马其顿语,俄语,塞尔维亚语,乌克兰语) 一般推荐使用 KOI8-R codepage
nls iso8859-6 – 阿拉伯语.
nls iso8859-7 – 现代希腊语
nls iso8859-8 – 希伯来语
nls iso8859-9 – Latin 5 字符集,(去掉了 Latin 1 中不经常使用的一些冰岛语字符而代以土耳其语字符)
nls iso8859-10 – Latin 6 字符集,(因纽特 (格陵兰) 语,萨摩斯岛语等 Latin 4 中没有包括的北欧语种)
nls iso8859-15 – Latin 9 字符集,是 Latin 1 字符集的更新版本,去掉一些不常用的字符,增加了对爱莎尼亚语的支持,修正了法语和芬兰语部份,增加了欧元字符)
nls koi8-r – 俄语的缺省支持
ASP 和 SAP 中的 Code Page 区别
ASP 中
CodePage 的作用,是决定页面以何种编码方式显示动态内容。当页面被服务器处理之后,页面将以 CodePage 设定的编码输出到客户端。当然,CodePage 的参数需正确,否则,将产生错误信息 “CodePage 值无效。指定的 CodePage 值无效(事件 ID: 0204)”。
如果 CodePage 没有设置,则服务器使用默认的 CodePage 加载到你的 Session 里面,使用程序代码:Response.Write (Session.CodePage) 可以查看你当前使用的 CodePage。
LANGUAGE=“VBSCRIPT” 和 LANGUAGE=“javascript”,申明 ASP 当前使用的编程脚本分别为 VBSCRIPT 和 javascript。
一般在程序第一行进行申明。当使用该脚本申明后,以下所有程序运用全得符合该脚本语言的所有语法,两者不能混淆使用,否则出错。在写 ASP 时,一般不做限定,因为经常会在一 ASP 页面写不同的脚本,当然这也是以牺牲执行效率为代价的。
CodePage:可读 / 可写。整型。用于定义在网页浏览器中显示页面内容所使用的代码页。代码页是字符集的数字值,不同的语言使用不同的代码页。例如,ANSI 代码页 1252 通常用于西欧语言,日语使用代码页 932,简体中文使用代码页 936。当在国际网页空间上传内容或提取数据库记录后出现乱码时,可以使用此方法解决这类问题。
SAP 中
最经常使用的读取数据的方法就是使用 GUI_UPLOAD 这个 FM( Function Module,函数模块),其中有个 CODEPAGE, 是用来指定代码页的。
Siebel Value | SAP 代码页 | 描述 |
---|---|---|
CP1252 | 1100 | SAP 拉丁语 - 1 - ISO8859-1 - 代码页 |
ISO-8859-2 | 1402 | SAP 拉丁语 - 2 - ISO8859-2 |
ISO-8859-5 | 1500 | SAP 西里尔文 - ISO8859-5 |
CP1254 | 1610 | SAP 土耳其语 - ISO8859-9 |
CP1253 | 1700 | SAP 希腊语 - ISO8859-7 - 不完全匹配 |
CP1255 | 1800 | SAP 希伯来语 - ISO8859-8 - 不完全匹配 |
CP932 | 8000 | SAP Shift-JIS |
CP950 | 8300 | SAP 繁体中文 |
CP936 | 8400 | SAP 简体中文 |
CP949 | 8500 | SAP 韩文 |
CP874 | 8600 | SAP 泰文 |
OEM (IBM PC) 代码页
- 437 — 最初的 IBM PC 代码页,实现了扩展 ASCII 字符集
- 737 — 希腊语
- 850 —“多语言 (Latin-1)” (西欧语言)
- 852 —“斯拉夫 (Latin-2)” (中欧及东欧语言)
- 855 — 西里尔 (Cyril) 字母
- 857 — 土耳其语
- 858 — 带欧元符号的 “多语言”
- 860 — 葡萄牙语
- 861 — 冰岛语
- 863 — 法语加拿大英语
- 865 — 北欧
- 866 — 西里尔 (Cyril) 字母
- 869 — 希腊语
代码页 819 实现了拉丁语 (Latin-1)(ISO/IEC 8859-1),用于 IBM AS/400 小型机。
中日韩语言代码页
既是 OEM 代码页,也是 Windows 代码页。
- 932 — 日 文 (shift_jis)
- 936 — 简体中文(GBK)
- 949 — 韩文
- 950 — 繁体中文(大五码)
GB xxxxxx
1. GB2312
GB2312 (1980 年) 一共收录了 7445 个字符,包括 6763 个汉字和 682 个其它符号。汉字区的内码范围高字节从 B0-F7,低字节从 A1-FE,占用的码位是 72*94=6768。其中有 5 个空位是 D7FA-D7FE。
2. GBK
在 windows 中的代码页是 CP936,GBK 最初是由微软对 GB2312 的扩展,也就是 CP936 字码表 (Code Page 936) 的扩展(原来的 CP936 和 GB 2312-80 一模一样),最初出现于 Windows 95 简体中文版中,由于 Windows 产品的流行和在大陆广泛被使用,中华人民共和国国家有关部门将其作为技术规范。
注意 GBK 并非国家正式标准,只是国家技术监督局标准化司、电子工业部科技与质量监督司发布的 “技术规范指导性文件”。
虽然 GBK 收录了所有 Unicode 1.1 及 GB 13000.1-93 之中的汉字,但是编码方式与 Unicode 1.1 及 GB 13000.1-93 不同。仅仅是 GB 2312 到 GB 13000.1-93 之间的过渡方案。GBK 收录了 21886 个符号,它分为汉字区和图形符号区。汉字区包括 21003 个字符。
GBK 作为对 GB2312 的扩展,在现在的 windows 系统中仍然使用代码页 CP936 表示,但是同样的 936 的代码页跟一开始的 936 的代码页只支持 GB2312 编码不同,现在的 936 代码页支持 GBK 的编码,GBK 同时也向下兼容 GB2312 编码。
3. GB18030
2000 年的 GB18030 取代了 GBK1.0 的正式国家标准。该标准收录了 27484 个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的 PC 平台必须支持 GB18030,对嵌入式产品暂不作要求。所以手机、MP3 一般只支持 GB2312。
GB18030 在 windows 中的代码页是 CP54936。
4. GB13000
GB13000 等同于国际标准的《通用多八位编码字符集 (UCS)》 ISO10646.1,就是等同于 Unicode 的标准,代码页等等的都使用 UTF 的一套标准。
从 ASCII、GB2312、GBK 到 GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。
区分中文编码的方法是高字节的最高位不为 0。按照程序员的称呼,GB2312、GBK 到 GB18030 都属于 DBCS(Double Byte Character Set,双字节字符集)。
其他代码页
- 10000 — Macintosh Roman encoding (followed by several other Mac character sets)
- 10007 — Macintosh Cyrillic encoding
- 10029 — Macintosh Central European encoding
- 1200 — UCS-2LE Unicode 小端序 (BMP 的 ISO 10646, UTF-16LE )
- 1201 — UCS-2BE Unicode 大端序 (unicodeFFFE)
- 65000 — UTF-7 Unicode
- 65001 — UTF-8 Unicode
Windows (ANSI) 代码页
- 874 — 泰文字母
- 1250 — 东欧拉丁字母
- 1251 — 古斯拉夫语
- 1252 — 西欧拉丁字母 ISO-8859-1.
- 1253 — 希腊语
- 1254 — 土耳其语
- 1255 — 希伯来语
- 1256 — 阿拉伯语
- 1257 — 巴尔
- 1258 — 越南
- 1254 — 土耳其语
斯拉夫语的 MS-DOS 内码表 855 与斯拉夫语的 Windows 内码表 1251 以及斯拉夫语的 Macintosh 内码表 10007 不同。
Windows-1252 与 ISO-8859-1 并不完全一致。ISO-8859-1 在 0x80-0x9F 范围的控制字符,在 Windows-1252 中被可打印字符取代。由于在 web 网页中,ASCII 控制字符不起作用,所以网页一般用 Windows-1252 代码页标记替代 ISO-8859-1 标记。
Code Page 和 Unicode 的区别
Code Page 和 Unicode 是处理全球语言字符的两种解决方案,但其工作原理和特性有所不同。
Unicode 为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。而 Code Page 采取重复的编号,根据不同的 Code Page 来决定一个编号是什么字符。同一个编号在不同的 Code Page 下代表不同的字符。
Unicode
- 为每个语言中的每个字符提供了唯一的二进制编码,确保字符在不同系统和平台上的一致性和互操作性。
- 成为跨语言、跨平台进行文本处理和转换的标准选择。
- 是一个通用的字符编码标准,为每个字符分配了唯一的代码点(code point),以满足跨语言、跨平台进行文本转换和处理的要求。
Code Page
- 是一种早期的字符编码方案,使用不同的编号来映射字符集中的字符。
- 每个 Code Page 都有自己的编号表,相同的编号在不同的 Code Page 下可以代表不同的字符。
- 通常用于早期的操作系统和应用程序中,局限于特定语言或区域,并不具备跨语言互操作性。
- 存在很多限制和问题,例如字符集不够完整、编码不够统一、跨平台和跨语言转换困难等。
在实际应用中,特别是在多语言环境下,Unicode 的使用已经成为主流,因为它提供了更广泛的字符覆盖范围和更高的兼容性。
Via: 网络整理 暂记 待修订
Code Page Identifiers - Win32 apps | Microsoft Learn
https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers?redirectedfrom=MSDN
Windows code page - Wikipedia
https://en.wikipedia.org/wiki/Windows_code_page