ANSI、GBK、Unicode等等iconv转换详解一文搞定
本文首发于公众号“嵌入式软件实战派”,关注后获得更多精品干货。
> 网页上的编码
也许你会问,自从有了互联网,全世界都近在咫尺,那么网页上的编码时什么,是怎么做到不同语言文字国家的浏览器都可以显示正确的文字字符呢?
下面举个例子,用古老的IE浏览器打开度娘主页,就长这样,如果是欧美国家打开应该也是这样,不是说字符编码不一样的吗?
其实,窍门在这,在网页右键,选择“编码”,然后可以看到子菜单的选择
将其改成“简体中文(GB2312)”会怎样呢?
呵呵,乱码了……
在我大天朝用御用的GB2312编码看不了度娘首页?别急,看官请息怒。
打开度娘首页的源码(即右键,选择查看源码),你会找到“charset=utf-8”的字样。
这个内容实际是告你浏览器,你要用UTF-8的编码格式来解释我的网页内容。
> 文本编辑器里面的编码
在文本上写代码写文章,我怎么知道它是用什么编码的呢?
一般编译器都会有个默认编码,或者也可以自己选择,例如Notepad++的“编码”菜单就有很多选择。
那么,疑问又来了:什么是ANSI?UTF-8和UTF-8-BOM是啥区别?UCS-2的Big Endian和Little Endian是什么东西?
> ANSI
为使计算机支持更多语言,通常使用 0x80~0xFFFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。
不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GB2312编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI 编码代表 JIS 编码。
在简体中文的windows系统上打开记事本输入文字字符,其格式默认就是ANSI即GB2312,当然你也可以另存为其他格式,如下图
不知你有没有跟欧美或者日本人在工作上合作过,有时候他们发过来的文件文件名就是乱码的。不知情的你会抱怨他们发些乱七八糟的东西过来……
就以日本的为例,他们用日语的windows系统,当然他们的ANSI就是JIS了,文件名字字符编码也就是JIS的,用简体中文的windows打开当然看到乱码了。
怎么办?你们商量好统一一种格式咯,或者用ASCII的英文就好了。
windows的ANSI字符编码可以改吗?可以!打开控制面板,找到语言区域设置即可。
> UTF-8的BOM
举例说明:
在Notepad++的UTF-8格式编码上写个“中”子,查看其二进制为
改为UTF-8-BOM,再写一次“中”,看起二进制编码是
很明显,带BOM的多了个EF BB BF的头。
因为Unicode可以采用16位或者32位编码,所以计算机在处理时需要知道其字节顺序,BOM ( Byte Order Mark)就是用来标识字节流的字节顺序的,但字节顺序这个 概念对UTF-8来说是没有意义的,所以BOM对UTF-8同样没有意义。但Unicode标准却BOM在UTF-8编码格式中存在。其存在位置在文件开 头,以三个字节0xEF, 0xBB, 0xBF表示。
UTF-8编码不推荐使用无意义的BOM,但许多Windows程序却在保存UTF-8编码的文件时将其存为带BOM的格式(即在文件开头加上0xEFBBBF三个字节),这么干的就包括Windows记事本。
UCS-2的Big Endian和Little Endian
举例说明,在UCS-2 Big Endian编码格式下输入“中”字,看其二进制编码
在UCS-2 Little Endian编码格式下输入“中”字,看其二进制编码
我们都可以知道或者查到“中”字的unicode是4E2D,那么其存在两种表达形式4E2D或者2D4E,这就是Big Endian和Little Endian的缘故了。
那么这个FE FF或者FF FE又是啥?其实是告诉你这个文档后面的内容字符是Big Endian还是Little Endian。
> 代码页
我们常常会遇到一个叫“代码页”的东西,即code page,这是个什么东西呢?
早期,代码页是IBM称呼计算机的BIOS所支持的字符集编码。当时通用的操作系统都是命令行界面,这些操作系统直接使用BIOS提供的字符绘制功能来显示字符(或者是一组嵌入在显卡字符生成器中的字形)。这些BIOS代码页也被称为OEM代码页。图形操作系统使用自己的字符呈现引擎(rendering engine),可以支持多个不同的字符集编码,这类代码页被称作ANSI代码页。早期IBM和微软内部使用数字来标记不同的编码字符集,不同的厂商对同一个字符集编码使用各自不同的名称。例如,UTF-8在IBM称作代码页1208,在微软称作代码页65001,在SAP称作代码页4110。
以下是来源于网络的一些代码页和字符编码格式的对照:
代码页 |
简称 |
全称 |
37 |
IBM037 |
IBM EBCDIC (US-Canada) |
437 |
IBM437 |
OEM United States |
500 |
IBM500 |
IBM EBCDIC (International) |
708 |
ASMO-708 |
Arabic (ASMO 708) |
720 |
DOS-720 |
Arabic (DOS) |
737 |
ibm737 |
Greek (DOS) |
775 |
ibm775 |
Baltic (DOS) |
850 |
ibm850 |
Western European (DOS) |
852 |
ibm852 |
Central European (DOS) |
855 |
IBM855 |
OEM Cyrillic |
857 |
ibm857 |
Turkish (DOS) |
858 |
IBM00858 |
OEM Multilingual Latin I |
860 |
IBM860 |
Portuguese (DOS) |
861 |
ibm861 |
Icelandic (DOS) |
862 |
DOS-862 |
Hebrew (DOS) |
863 |
IBM863 |
French Canadian (DOS) |
864 |
IBM864 |
Arabic (864) |
865 |
IBM865 |
Nordic (DOS) |
866 |
cp866 |
Cyrillic (DOS) |
869 |
ibm869 |
Greek, Modern (DOS) |
870 |
IBM870 |
IBM EBCDIC (Multilingual Latin-2) |
874 |
windows-874 |
Thai (Windows) |
875 |
cp875 |
IBM EBCDIC (Greek Modern) |
932 |
shift_jis |
Japanese (Shift-JIS) |
936 |
gb2312 |
Chinese Simplified (GB2312) |
949 |
ks_c_5601-1987 |
Korean |
950 |
big5 |
Chinese Traditional (Big5) |
1026 |
IBM1026 |
IBM EBCDIC (Turkish Latin-5) |
1047 |
IBM01047 |
IBM Latin-1 |
1140 |
IBM01140 |
IBM EBCDIC (US-Canada-Euro) |
1141 |
IBM01141 |
IBM EBCDIC (Germany-Euro) |
1142 |
IBM01142 |
IBM EBCDIC (Denmark-Norway-Euro) |
1143 |
IBM01143 |
IBM EBCDIC (Finland-Sweden-Euro) |
1144 |
IBM01144 |
IBM EBCDIC (Italy-Euro) |
1145 |
IBM01145 |
IBM EBCDIC (Spain-Euro) |
1146 |
IBM01146 |
IBM EBCDIC (UK-Euro) |
1147 |
IBM01147 |
IBM EBCDIC (France-Euro) |
1148 |
IBM01148 |
IBM EBCDIC (International-Euro) |
1149 |
IBM01149 |
IBM EBCDIC (Icelandic-Euro) |
1200 |
utf-16 |
Unicode |
1201 |
unicodeFFFE |
Unicode (Big-Endian) |
1250 |
windows-1250 |
Central European (Windows) |
1251 |
windows-1251 |
Cyrillic (Windows) |
1252 |
Windows-1252 |
Western European (Windows) |
1253 |
windows-1253 |
Greek (Windows) |
1254 |
windows-1254 |
Turkish (Windows) |
1255 |
windows-1255 |
Hebrew (Windows) |
1256 |
windows-1256 |
Arabic (Windows) |
1257 |
windows-1257 |
Baltic (Windows) |
1258 |
windows-1258 |
Vietnamese (Windows) |
1361 |
Johab |
Korean (Johab) |
10000 |
macintosh |
Western European (Mac) |
10001 |
x-mac-japanese |
Japanese (Mac) |
10002 |
x-mac-chinesetrad |
Chinese Traditional (Mac) |
10003 |
x-mac-korean |
Korean (Mac) |
10004 |
x-mac-arabic |
Arabic (Mac) |
10005 |
x-mac-hebrew |
Hebrew (Mac) |
10006 |
x-mac-greek |
Greek (Mac) |
10007 |
x-mac-cyrillic |
Cyrillic (Mac) |
10008 |
x-mac-chinesesimp |
Chinese Simplified (Mac) |
10010 |
x-mac-romanian |
Romanian (Mac) |
10017 |
x-mac-ukrainian |
Ukrainian (Mac) |
10021 |
x-mac-thai |
Thai (Mac) |
10029 |
x-mac-ce |
Central European (Mac) |
10079 |
x-mac-icelandic |
Icelandic (Mac) |
10081 |
x-mac-turkish |
Turkish (Mac) |
10082 |
x-mac-croatian |
Croatian (Mac) |
20000 |
x-Chinese-CNS |
Chinese Traditional (CNS) |
20001 |
x-cp20001 |
TCA Taiwan |
20002 |
x-Chinese-Eten |
Chinese Traditional (Eten) |
20003 |
x-cp20003 |
IBM5550 Taiwan |
20004 |
x-cp20004 |
TeleText Taiwan |
20005 |
x-cp20005 |
Wang Taiwan |
20105 |
x-IA5 |
Western European (IA5) |
20106 |
x-IA5-German |
German (IA5) |
20107 |
x-IA5-Swedish |
Swedish (IA5) |
20108 |
x-IA5-Norwegian |
Norwegian (IA5) |
20127 |
us-ascii |
US-ASCII |
20261 |
x-cp20261 |
T.61 |
20269 |
x-cp20269 |
ISO-6937 |
20273 |
IBM273 |
IBM EBCDIC (Germany) |
20277 |
IBM277 |
IBM EBCDIC (Denmark-Norway) |
20278 |
IBM278 |
IBM EBCDIC (Finland-Sweden) |
20280 |
IBM280 |
IBM EBCDIC (Italy) |
20284 |
IBM284 |
IBM EBCDIC (Spain) |
20285 |
IBM285 |
IBM EBCDIC (UK) |
20290 |
IBM290 |
IBM EBCDIC (Japanese katakana) |
20297 |
IBM297 |
IBM EBCDIC (France) |
20420 |
IBM420 |
IBM EBCDIC (Arabic) |
20423 |
IBM423 |
IBM EBCDIC (Greek) |
20424 |
IBM424 |
IBM EBCDIC (Hebrew) |
20833 |
x-EBCDIC-KoreanExtended |
IBM EBCDIC (Korean Extended) |
20838 |
IBM-Thai |
IBM EBCDIC (Thai) |
20866 |
koi8-r |
Cyrillic (KOI8-R) |
20871 |
IBM871 |
IBM EBCDIC (Icelandic) |
20880 |
IBM880 |
IBM EBCDIC (Cyrillic Russian) |
20905 |
IBM905 |
IBM EBCDIC (Turkish) |
20924 |
IBM00924 |
IBM Latin-1 |
20932 |
EUC-JP |
Japanese (JIS 0208-1990 and 0212-1990) |
20936 |
x-cp20936 |
Chinese Simplified (GB2312-80) |
20949 |
x-cp20949 |
Korean Wansung |
21025 |
cp1025 |
IBM EBCDIC (Cyrillic Serbian-Bulgarian) |
21866 |
koi8-u |
Cyrillic (KOI8-U) |
28591 |
iso-8859-1 |
Western European (ISO) |
28592 |
iso-8859-2 |
Central European (ISO) |
28593 |
iso-8859-3 |
Latin 3 (ISO) |
28594 |
iso-8859-4 |
Baltic (ISO) |
28595 |
iso-8859-5 |
Cyrillic (ISO) |
28596 |
iso-8859-6 |
Arabic (ISO) |
28597 |
iso-8859-7 |
Greek (ISO) |
28598 |
iso-8859-8 |
Hebrew (ISO-Visual) |
28599 |
iso-8859-9 |
Turkish (ISO) |
28603 |
iso-8859-13 |
Estonian (ISO) |
28605 |
iso-8859-15 |
Latin 9 (ISO) |
29001 |
x-Europa |
Europa |
38598 |
iso-8859-8-i |
Hebrew (ISO-Logical) |
50220 |
iso-2022-jp |
Japanese (JIS) |
50221 |
csISO2022JP |
Japanese (JIS-Allow 1 byte Kana) |
50222 |
iso-2022-jp |
Japanese (JIS-Allow 1 byte Kana - SO/SI) |
50225 |
iso-2022-kr |
Korean (ISO) |
50227 |
x-cp50227 |
Chinese Simplified (ISO-2022) |
51932 |
euc-jp |
Japanese (EUC) |
51936 |
EUC-CN |
Chinese Simplified (EUC) |
51949 |
euc-kr |
Korean (EUC) |
52936 |
hz-gb-2312 |
Chinese Simplified (HZ) |
54936 |
GB18030 |
Chinese Simplified (GB18030) |
57002 |
x-iscii-de |
ISCII Devanagari |
57003 |
x-iscii-be |
ISCII Bengali |
57004 |
x-iscii-ta |
ISCII Tamil |
57005 |
x-iscii-te |
ISCII Telugu |
57006 |
x-iscii-as |
ISCII Assamese |
57007 |
x-iscii-or |
ISCII Oriya |
57008 |
x-iscii-ka |
ISCII Kannada |
57009 |
x-iscii-ma |
ISCII Malayalam |
57010 |
x-iscii-gu |
ISCII Gujarati |
57011 |
x-iscii-pa |
ISCII Punjabi |
65000 |
utf-7 |
Unicode (UTF-7) |
65001 |
utf-8 |
Unicode (UTF-8) |
65005 |
utf-32 |
Unicode (UTF-32) |
65006 |
utf-32BE |
Unicode (UTF-32 Big-Endian) |
> iconv
世界上这么多字符编码,那么做到相互转换呢?你是不是还苦苦寻址转换函数?
拜托,我一个库就搞定了,你不需要这么多,那你随意挑几个去用。
啥?iconv啊!GNU Linux上的好东西。详见http://www.gnu.org/software/libiconv/
实际上,iconv是一个linux命令程序,它的库叫libiconv,能将一种字符格式转换成另一种。如:iconv -f EUC-JP-MS -t UTF-8 file1 -o file2
命令参数解释: -f encoding :把字符从encoding编码开始转换。 -t encoding :把字符转换到encoding编码。 -l :列出已知的编码字符集合 -o file :指定输出文件 -c :忽略输出的非法字符 -s :禁止警告信息,但不是错误信息 --verbose :显示进度信息 -f和-t所能指定的合法字符在-l选项的命令里面都列出来了。 |
iconv支持的范围非常广:
分类 | 字符编码 |
European languages | ASCII, ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16}, KOI8-R, KOI8-U, KOI8-RU, CP{1250,1251,1252,1253,1254,1257}, CP{850,866,1131}, Mac{Roman,CentralEurope,Iceland,Croatian,Romania}, Mac{Cyrillic,Ukraine,Greek,Turkish}, Macintosh |
Semitic languages | ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic} |
Japanese | EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1, ISO-2022-JP-MS |
Chinese | EUC-CN, HZ, GBK, CP936, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, BIG5-HKSCS:2004, BIG5-HKSCS:2001, BIG5-HKSCS:1999, ISO-2022-CN, ISO-2022-CN-EXT |
Korean | EUC-KR, CP949, ISO-2022-KR, JOHAB |
Armenian | ARMSCII-8 |
Georgian | Georgian-Academy, Georgian-PS |
Tajik | KOI8-T |
Kazakh | PT154, RK1048 |
Thai | ISO-8859-11, TIS-620, CP874, MacThai |
Laotian | MuleLao-1, CP1133 |
Vietnamese | VISCII, TCVN, CP1258 |
Platform specifics | HP-ROMAN8, NEXTSTEP |
Full Unicode |
UTF-8 UCS-2, UCS-2BE, UCS-2LE UCS-4, UCS-4BE, UCS-4LE UTF-16, UTF-16BE, UTF-16LE UTF-32, UTF-32BE, UTF-32LE UTF-7 C99, JAVA Full Unicode, in terms of uint16_t or uint32_t (with machine dependent endianness and alignment) |
char, wchar_t | The empty encoding name "" is equivalent to "char": it denotes the locale dependent character encoding. |
那么字符编码到底是怎么转换的呢?
有两种:查表法,还有直接转换。
第一种很好理解,做一个编码A和编码B的字符对照表,然后查表即可,例如GB2312转UNICODE的或者反过来。
这里就定义了GB2312格式对照unicode的编码。
函数是
以上这个函数名mbtowc是multi-byte to wide char的意思。
第二种,直接转换呢?
字符编码格式一样,只是表达形式不一样,就可以直接转换,例如UTF-8转UTF-16等。
这一切的转换方法,iconv都已经做好了,而且经过了大量的验证,你就不要在网上搜转换方法了。
这里不得不提的是,这个iconv用了一个巧妙的方法,所有的这些表和函数都是定义在一个.h文件里面。
啥?函数不是应该写在c文件吗?上学老师都这么说的啊!
研究下它的makefile你就会懂了,模块化做的非常好,不需要的随意注释掉即可。
如果你不知道iconv怎么获取或者从官网下载不了?请关注公众号回复“iconv”获得下载链接。
关注公众号号“嵌入式软件实战派”,获得更多知识干货。
ANSI、GBK、Unicode等等iconv转换详解一文搞定相关推荐
- 标准差详解-一文搞懂标准差的含义
标准差详解-一文搞懂标准差的含义 转载自 样本标准差的意义是什么? 的第一个回答
- Shell脚本详解---一篇搞定
有道云分享链接 1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都 ...
- java中equals方法重写详解(彻底搞定)
首先上案例: public static void main(String[] args){String str1 = "abc";String str2 = "abc& ...
- Spring AOP详解一文搞懂@Aspect、@Pointcut、@Before、@Around、@After、@AfterReturning、@AfterThrowing
文章目录 1.AOP是什么 2.AOP中注解的含义 3.Pointcut切入点的语法 4.AOP代码实现 1.AOP是什么 AOP:Aspect Oriented Programming,翻译过来就是 ...
- VSCode安装教程(图文详解,简单搞定)
1.下载 https://code.visualstudio.com/download 是Microsoft(微软的产品) User Installer版:会安装在当前计算机帐户目录,意味着如果使用另 ...
- UNICODE与UTF-8的转换详解
UNICODE与UTF-8的转换详解 1 编码 在计算机中,各种信息都是以二进制编码的形式存在的,也就是说,不管是文字.图形.声音.动画,还是电影等各种信息,在计算机中都是以0和1组成的二进制代码表示 ...
- UNICODE与 UTF8的转换详解
转载请注明出处: http://www.ins1000.cn/KnowledgeActionForReader?action=read&id=104 源文件下载地址:UTF- 8的转换详解(W ...
- UNICODE与 UTF-8 的转换详解
UNICODE与 UTF-8的转换详解 unicode 只是一种编码方式,而utf-8是unicode的一种保存或传输方式. 1 编码 在计算机中,各种信息都是以二进制编码的形式存在的,也就是说,不 ...
- python中时间戳、字符串之间转换详解
[转载]python中时间戳.字符串之间转换详解 (2013-04-30 17:36:07) 转载▼ 标签: 转载 原文地址:python中时间戳.字符串之间转换详解作者:doris0920 1)秒数 ...
最新文章
- Sicily 1153: 马的周游问题(DFS+剪枝)
- linux下定义删除变量
- 设计模式(装饰模式)
- java 反射 成员变量_java基础--反射(成员变量)
- php 伪静态规则,在线将Apache Rewrite Rules伪静态规则转换为Nginx Rewrite伪静态规则...
- 函数别名c语言,C最佳实践 – 函数类型别名std :: function或T.
- java查询数据库数据放到Excel下载
- 复杂性研究面临的难题
- python大数据工程师招聘_大数据工程师是做什么的为什么招聘网上薪资都好高啊?...
- 菜谱中英文对照Menu with English
- 因为文件共享不安全,所以你不能连接到文件共享。此共享需要过时的SMB1协议
- 2014-2015 少年辛苦终身事,莫向光阴惰寸功
- Lucas(卢卡斯)定理 【数论】
- web自动化笔记八:滚动条处理和窗口截屏
- 管理学中的 Expectancy Theory - 期望理论
- 医疗器械网电源部分使用一个保险丝还是两个保险丝?
- [转]GDI 泄漏检测方法
- 深度学习(1) ——图像分类
- 数码摄影入门之十 数码相片后期处理
- 国内互联网公司梯队划分,百度掉队!阿里,腾讯,华为第一挡 !
热门文章
- 伦敦金k线图基础知识有多重要?
- 同一个世界 三生梦醒(V 1.3.2)
- python 网站开发环境_Python开发环境搭建
- 备战2021年金三银四,分享美团三面总结的一些经验,面试题全集和学习文档、视频,希望大家能够升职加薪吧!
- android控制外接显示器的亮度,让外接屏实现一键调亮度调音量,一个 MonitorControl 就够了...
- Python Reportlab表 换行
- IDEA控制台乱码 淇℃伅
- 51与STM32单片机架构(内核和片上外设)的区别汇总+拓展
- vue 读取本地文件内容
- html验证用户名和密码,如何用javascript判断用户名和密码是否为空?