Welcome 微信登录

首页 / 操作系统 / Linux / Android Media 播放mp3时ID3 tag 显示乱码的探究分析。

我们从Windows的中文操作系统下,下载下来mp3,Tag正常显示,推进Android机后,却出现乱码,这是为什么呢?之所以在中文系统中没有特别的问题,是因为通常电脑生成的MP3简体中文ID3标签是ID3V2.3版本,编码是ANSI,GB2312/GBK从双字节上兼容ANSI标准。而在UTF-8/Unicode为标准的系统中如Linux(Ubuntu),Android中就容易出现这种问题。解决办法先明确几个知识点:首先明确一点,文件不存在什么编码(归根结底文件都是二进制文件,用ue打开可以看到都是一个个的16进制数),只有文件中的字符才可以说编码。unicode和ansi都是字符代码的一种表示形式。使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。 不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。常见编码介绍ansi编码最初的计算机是又8个晶体管,通过晶体管的开合与排列可以表示数种状态,所以一个字节就定义为8bit,而一个bit只能有0,1开关的表示,2的8次方是256,所以最初的计算机只能表示256种状态。人们定义了前32个为状态字符比如翻页,换行,发出(嘟)的声音等,后来人们为了用计算机存储文字,又把空格,英文字母,数字等加进了进来,总共使用了127个,这时候大家把这个存储方案叫做ANSI的ASCII编码[American Standard Code for Information Interchange,美国信息互换标准代码](http://www.dreamdu.com/xhtml/ascii/),这个表存储英文已经没有 问题了,但是127个里并不包含其它欧洲国际的文字,人们又继续扩展ASCII表的内容,加入了一些字符,与一些画表格的符号,直接扩展到255个。ASCII和Ansi编码     字符内码(charcter code)指的是用来代表字符的内码.读者在输入和存储文档时都要使用内码,内码分为     单字节内码 -- Single-Byte character sets (SBCS),可以支持256个字符编码.     双字节内码 -- Double-Byte character sets)(DBCS),可以支持65000个字符编码. 前者即为ASCII编码,后者对应ANSI. 至于简体中文编码GB2312,实际上它是ANSI的一个代码页936GB2312与GBK国人发现只使用ASCII表根本无法表示汉字!怎么办?没有什么能难道我们!于是我们发明了GB2312编码,此编码完全忽略了ASCII表中 127位后面的内容,127位前面的内容保留,如果两个字节同时大于127(7F)就认为这两个字节表示一个汉字,同时像标点、字母也都重新使用两个字节 定义了一遍,这就是我们经常说的 全角,这种方案可以表示6000种文字。但是中国的文字太复杂6000个字也不够用,人们开始扩展GB2312,规定只要一个字节大于127,这个字节和后面的字节组合起来就代表一个汉字,这种编码成为GBK,于是又增加了20000多个汉字!这样很多国家都开始定义自己的编码了,日本,韩国等。甚至连中国的台湾省都定义了一种编码 BIG5。所以在当时一个程序要想适应多国语言简直要把人郁闷死。如果搞过Windows编程的人应该知道,win里面有多字节字符集MBCS(multi-byte character set)的说法,而且MBCS包含两种字符类型,单字节字符SBCS(single-byte characters set)和双字节字符(double-byte characters set)DBCS。我们的GBK与GB2312都是DBCS。所以我们在编程时经常遇到一个中文字符等于两个英文字符的事情。BIG5与日本韩国的编码也 都属于DBCS。这下清楚了吧,根本没什么ansi文件或gb2312文件,文件打开时会根据操作系统的编码方式(就是安装在操作系统中的编码解析方式)来尝试打开文件,如果安装了中文编码,就把ansi文件当作中文打开,如果日文编码,就当作日文打开。UNICODE与UTF-8ISO最后提出了UNICODE(Universal Multiple-Octet Coded Character Set,简称 UCS)编码来解决所有的问题。UNICODE编码方式规定使用两个字节(16位)表示表示一个字符,算算2的16次方是多少?原来ANSI规定的都扩充为2字节,并且把所有已知的语言都编码进UNICODE。UNICODE可以表示65536个字符。这下多国语言程序开始高兴了,使用UNICODE全部搞定!于是微软重现编辑Windows内核,完全使用UNICODE编码,搞过win编程的人应该都知道,以A或W结尾的函数,还有灵巧的_T宏吧?虽然UNICODE有很多优点,但是缺点也不少,我先总结我知道的两点:1,狂占空间,以前一个字节可以表示,现在却要用两个字节了,网络上有80%属于英文字符,这下网络几乎要扩大一倍!所以又有人研究出来了UTF-8(Unicode Translation Format - 8)编码,UNICODE转换格式,对于常用字符使用单字节,汉字等使用双字节。8代表每次在网络上传输8位,如果是UTF-16就是每次传输16位。搞 过网络编程的朋友应该知道,字节序(就是字节的排放顺序)分为两种,主机字节序与网络字节序,就是大头(俗称)在前,小头在前的问题,在网络上面传输的流 的字节序很可能是不一致的,于是需要使用一种方法通知接收端,传输流的字节序。有人发明了一种简单的方法,在每个流的开始加上FFEF或EFFF,分别主 机与网络字节序,我们可以使用记事本保存一个UNICODE文件,再使用ue打开看看(HEX方式打开)。所以有时候网页传到网上,在网页最开始的地方会 出现一个字符,这个有时候很令人费解。用记事本新建立两个文件存为UNICODE与UNICODE big endian模式,输入梦之都,保存再用ue打开。UNICODEFF FE A6 68 4B 4E FD 90UNICODE big endianFE FF 68 A6 4E 4B 90 FD (观察,没两个字节和上面的对比)2,UNICODE与GBK等两字节编码完全不兼容,无法找到一种简单的方式转换(只能使用查找表的方式)这点我们可以使用记事本新建立两个文件一个ansi的文件,另一个utf8的文件,分别写入梦之都 ,保存。使用ue的hex模式打开我们会看到。UNICODEFF FE A6 68 4B 4E FD 90ansiC3 CE D6 AE B6 BC很著名的问题,如果用记事本输入“联通”保存,再打开,发现“联通”两个字没了!为什么没有了,大家可以自己分析一下。有人说这就是联通竞争不过移动的原因。清楚了这些,那么我想,必须先判断出是什么国家文字的歌曲,再用什么方式去解ANSI标准码 ,最后转换成utf-8显示。概括一句话:让utf-8正确解析双字节的ANSI。Ubuntu自动启动命令写法例子很全的笔记:Linux下字符编码转换相关资讯      Android教程 
  • Android 4.1+通过USB 连接Ubuntu进  (02/07/2013 08:44:43)
  • Android下使用最新FaceBook SDK 3.  (02/06/2013 16:13:37)
  • Android JNI 自定义对象为参数和返  (11/26/2012 19:04:48)
  • Android 获取手机应用信息  (02/06/2013 16:21:20)
  • Android设置Activity的显示位置  (02/01/2013 13:16:36)
  • Android中实现下拉刷新  (11/19/2012 15:26:23)
本文评论 查看全部评论 (0)
表情: 姓名: 字数