代码页

代码页是字符编码的别名，也稱内码表，是特定语言的字符集的一张表。 早期，代码页是IBM称呼计算机的BIOS所支持的字符集编码。当时通用的操作系统都是命令行界面，这些操作系统直接使用BIOS提供的字符绘制功能来显示字符（或者是一组嵌入在显卡字符生成器中的字形）。这些BIOS代码页也被称为OEM代码页。图形操作系统使用自己的字符呈现引擎（rendering engine），可以支持多个不同的字符集编码，这类代码页被称作ANSI代码页。 早期IBM和微软内部使用数字来标记不同的编码字符集，不同的厂商对同一个字符集编码使用各自不同的名称。例如，UTF-8在IBM称作代码页1208，在微软称作代码页65001，在SAP称作代码页4110。 1987年4月，IBM发布了PC-DOS 3.3，正式开始使用16比特的无符号整数标识不同的代码页。这时的PC机使用CGA显示系统的字符界面，绘制不同语言的字符依靠BIOS硬件厂商（在当时就是指制定业界标准的IBM）提供的功能。如果想更换所支持的字符集，就必须换上支持该字符集的ROM芯片。微软作为DOS操作系统的软件厂商，并不拥有绘制这些字符集的知识产权。所以这些字符集的绘制实现，称作OEM代码页。最常见、最具代表性的OEM代码页是"IBM PC或MS-DOS 代码页437"。 随着图形用户界面操作系统的广泛使用（最初被广为接受的是Windows 3.1），操作系统具有了字符绘制的功能。微软在Windows操作系统没有转向UTF-16作为内码实现之前（也就是在Windows 2000之前），针对不同的使用地区与国家，定义了一系列的支持不同语言字符集的代码页，被称作"Windows（或ANSI）代码页"。代表性的是实现了ISO-8859-1的代码页1252。 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代码页与ASCII代码页相同，例如对于简体中文的OEM代码页与ASCII代码页就是GBK代码页。而对于单字节编码的代码页，如英语、俄语等，OEM代码页与ASCII代码页一般不同。这是因为在MS-DOS时代，计算机只能使用字符界面在屏幕上画出表格的框线，所以OEM代码页要在单字节字符集中包含方框绘制字符；此外，OEM代码页437提供的有限的变音符号，只能覆盖法语、西班牙语、德语、意大利语、瑞典语的字母表。而在Windows的早期时代，仍然使用单字节字符集，这时就舍弃了这些不必要的方框绘制字符，取而代之的是丹麦语、挪威语、冰岛语、加拿大法语的变音符号。为此，一个用OEM代码页的字节流要在Windows上正确显示，就需要或者显式设定使用OEM代码页；或者要显式把OEM代码页的字节流转化为ASCII代码页的字符流，这需要使用Windows系统调用OemToChar()。 Windows代码页最初是根据ANSI草案实现的，这个草案最终成为ISO 8859-1。这是Windows代码页被称作ANSI的缘由。 874—泰文字母 1250—東歐拉丁字母 1251—古斯拉夫語 1252—西歐拉丁字母ISO-8859-1. 1253—希臘語 1254—土耳其語 1255—希伯來語 1256—阿拉伯語 1257—巴爾 1258—越南 Windows-1252与ISO-8859-1并不完全一致。ISO-8859-1在0x80-0x9F范围的控制字符，在Windows-1252中被可打印字符取代。由于在web网页中，ASCII控制字符不起作用，所以网页一般用Windows-1252代码页标记替代ISO-8859-1标记。 既是OEM代码页，也是Windows代码页。 936—简体中文（GBK） 950—繁體中文（大五碼） 932—日文（Shift_JIS） 949—韓文（EUC-KR） 20000（CNS）以EUC编码的繁体中文CNS编码 20002（Eten）以EUC编码的繁体中文倚天码 20936（GB2312-80）以EUC编码的简体中文GB2312编码（老设备或嵌入式设备常见） 50227（ISO-2022-GB）简体中文的Esc序列编码，纯ASCII 50229（ISO-2022-CNS）繁体中文的Esc序列编码，纯ASCII 52936（HZ-GB-2312）以~{和~}分隔的简体中文GB2312编码，纯ASCII 54936—简体中文（GB18030） 10000—Macintosh Roman encoding（followed by several other Mac character sets） 10007—Macintosh Cyrillic encoding 10029—Macintosh Central European encoding 1200—UCS-2LE Unicode 小端序 1201—UCS-2BE Unicode 大端序 65000—UTF-7 Unicode 65001—UTF-8 Unicode Windows平台上的GUI程序使用ANSI代码页，而在控制台程序使用OEM代码页（以便向后兼容）。这意味着，如果在记事本程序（notepad.exe）打开一个8位字符集编码的文本文件，将使用ANSI代码页；如果在命令行中用type命令显示这个文本文件的内容，将使用OEM代码页。这两个代码页在前128个字符的编码是一样的，但后128个字符的编码可能不一致。在Windows的命令行窗口通过标记、复制操作把一部分文本内容复制到记事本程序中，实际上是把Unicode格式的内容保存在剪贴板，使得这种文本复制保持了字符编码的透明转换。 对于Windows操作系统中的命令行窗口（Command Prompt），chcp命令在没有参数时，显示当前代码页；chcp命令带一个整数参数，则改变命令行窗口的当前代码页为参数所指定。 把UTF-8编码文本直接写到控制台，必须先使用函数SetConsoleOutputCP(65001)，然后使用puts一族的函数来输出文本。把UTF-8编码文本写入UTF-8文件时，可以直接使用窄字符输出函数。 在Windows API中，CP_ACP与CP_OEMCP分别表示当前系统的ANSI代码页与OEM代码页。对于CJK(多字节编码)的环境(泰文，日文，韩文，中文),CP_ACP与CP_OEMCP没有区别。对于非 CJK(单字节编码)的环境这两个代码页不同。 Windows的文件操作的API默认使用ASCII代码页(即CP_ACP)，设备的操作的函数使用OEM代码页(即CP_OEMCP)。读写console的函数是对console设备的操作，所以默认使用OEMCP。 Windows系统调用GetCPInfo()给出指定的代码页的信息。如东亚多字节代码页的缺省字符、前导字节的范围： { CPINFO info; UINT iCP = 932; //GBK GetCPInfo(iCP, &info); printf("Code page %d's default char is [%c]\n", iCP, info.DefaultChar[0]); printf("Max size of a char: %d\n", info.MaxCharSize); int i; const int iMaxLeadBytePairNum = 5; for (i = 0; i < iMaxLeadBytePairNum; i++) { if (info.LeadByte[i * 2] == 0 && info.LeadByte[i * 2 + 1] == 0) break; printf("Lead byte pair %d: 0x%02X-0x%02X\n", i, info.LeadByte[i * 2], info.LeadByte[i * 2 + 1]); } } IBM代碼頁（英文） IBM/ICU Charset Information Microsoft code page identifiers（Microsoft's list contains only code pages actively used by normal apps on Windows see also Torsten Mohrin's list for the full list of supported code pages） Shorter Microsoft list containing only the ANSI and OEM code pages but with links to more detail on each Character Sets And Code Pages At The Push Of A Button（页面存档备份，存于互联网档案馆）