词存在乱码怎么回事,显示很长的16进制转字符串乱码

博客访问: 624868
博文数量: 243
博客积分: 2500
博客等级: 少校
技术积分: 2652
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 其他
有些数据库中文乱码是因为字符集编码不同导致的,比如gbk字符集用2个byte保存一个中文字符,utf8用3个byte保存一个中文字符。
一些情况下,数据库字符集为ZHS16GBK,但是连接数据库的客户端环境用了UTF8的字符集。
插入中文时,只要在字段长度定义内,应用不会报错,但在其他GBK客户端以及在数据库内看起来,变成了乱码,如果表和记录比较多,要判断哪些记录是这种问题导致的乱码,可以通过字符转换来判断。
通过convert()转换字符集正常显示出中文。
通过以下一个小例子,说明这种问题:
数据库字符集ZHS16GBK
创建一张简单的表:
create table test1 (a varchar2(20));
在gbk的环境下客户端插入一条中文记录:
insert into test1 values('开放系统');
在utf8的环境下客户端插入一条中文记录:
insert into test1 values('这是乱码');
select a,length(a),lengthb(a),convert(a,'ZHS16GBK','UTF8'),length(convert(a,'ZHS16GBK','UTF8')) from test1;
A&&&&&&&&&&&&&& LENGTH(A) LENGTHB(A) CONVERT(A,'ZHS16GBK','UTF8')& LENGTH(CONVERT(A,'ZHS16GBK','UTF8'))
-------------- ---------- ---------- ----------------------------- ------------------------------------
杩欐槸涔辩爜&&&&&&&&&&& 6&&&&&&&& 12 这是乱码&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 4
开放系统&&&&&&&&&&&&&&& 4&&&&&&&&& 8 ??????&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 6
如果是由于UTF8和GBK编码不同导致的乱码,从上面的查询可以判断,如果LENGTH(A) > LENGTH(CONVERT(A,'ZHS16GBK','UTF8')),那么该记录可能就是乱码了。
阅读(3549) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。给你一个字符串,怎么判断该字符串是否含有乱码?
如题!!求方法?
以下是问题补充:
:如:生日??/ 孟絲??/strong&中的?,和黑色菱形字符等明显不可读,既不为中文简体又不是中文繁体的为乱码。
乱码本身就是相对的。。。
--- 共有 1 条评论 ---
补充了,麻烦看看有好的解决方法没,3Q。
首先是乱码如何定义,什么样的字符才叫乱码。
引用来自“KB325688”的答案首先是乱码如何定义,什么样的字符才叫乱码。赞同
你都没搞清楚乱码怎么来的,何来乱码。
--- 共有 1 条评论 ---
之前编码的程序有误,造成的。现在要把这些乱码剔出来、、
乱码是相对人的……计算机看起来都一样……对于计算机只有码~~~从来都不乱~~~~
--- 共有 3 条评论 ---
: 。那么你可以把这个字符串转换成byte数组,然后每次读取4位看它在utf-8中是否存在,存在则可以被解析成可表达字符,不存在则肯定是那个黑色的菱形,当然即便所有编码都在utf-8中也不一定其一定是人类可读的字符串。这个方法我很久以前试过,但是具体的细节都忘记了你多试试
: 我像个思路你看看可不可以实现,比如你现在转换的编码是utf-8编码,确定该字符串内的字符在utf-8编码中的范围是1-100
补充了,麻烦看看有好的解决方法没。。。谢谢
乱码是要解决的,不是来判断的!
--- 共有 3 条评论 ---
: http://www.oschina.net/question/338
之前提过问题,从根源上能解决以后得到的数据,但是之前得到的大批数据需要将有乱码的提取出来,然后没乱码的入库。
: 为什么有乱码,根源?解决不了?
处理方法就是抛弃,这样的数据毕竟是少数,或者是集中处理,不能让它入库,求解决方法!
乱码的问题一般都是字符编码不一致导致的,所以最好全部使用unicode
菰隆返笔舻诙,按你的定义,这种情况处理不了
--- 共有 3 条评论 ---
: 中文+英文也属于正常的,必要的标点也是正常的字符串。上面补充的是,明显不可读的字符才是乱码。
: 你的意思是中文字符以外的就定义为乱码?[\u4e00-\u9fa5]用这个区间试试
这个属于正常的字符串。。
汉字转换成对应的拼音字母,如果转不过来那就是乱码了!
引用来自“羡慕南飞的雁”的答案 汉字转换成对应的拼音字母,如果转不过来那就是乱码了! 貌似不是这个问题吧。哈。
--- 共有 2 条评论 ---
: 内码比对嘛。有什么想法不想法的。哈。
有啥好想法没、、、8512人阅读
字符编码与国际化
在Android系统设备中,如果有包含简体中文或繁体中文标题的歌曲时,有时候会看到乱码的现象,这是怎么回事?
要想知道答案,需要先了解下字符编码相关知识。
字符乱码问题由来
PC出现的早期,不同国家或区域对自己的文字制定了编码规范,大家各自为政,没有标准化
编码方案A: 代码 100 内容:”###“
编码方案B: 代码 100 内容:”@@@“
问题出现了:将编码方案A编码的内容使用在编码方案B中,会显示预期之外的内容如乱码等。
在此例子中,如果某文字用方案A编码,但是用方案B解码,则本应该显示”###“的文字会变成”@@@“
如何解决编码问题?
为解决各地区不同标准产生的编码问题,需要一种统一的编码方式,这便是ISO 10646和Unicode的由来。
各种不同的编码
1. ISO 10646
ISO 10646标准由国际标准化组织ISO颁布,用来实现全球所有文种的统一编码;
ISO 10646定义了标准字符集(Universal Character Set,UCS);
历史上存在两个独立的尝试创立单一字符集的组织,即国际标准化组织(ISO)和多语言软件制造商组成的统一码联盟即Unicode。
前者开发了ISO/IEC 10646 项目,后者开发了统一码项目。因此最初制定了不同的标准。
1991年前后,两个项目的参与者都认识到,世界不需要两个不兼容的字符集。于是,它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。
Unicode:统一码,为每一个字符定义唯一的代码(即一个整数);
目前的 Unicode 字符分为 17 组编排, 每组称为平面(Plane),而每平面拥有65536个代码点;
UCS-2即Unicode 0号平面字符集;
http://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84
http://zh.wikibooks.org/wiki/Unicode
Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF),如UTF-16,UTF-8等;
8-bit Unicode Transformation Format,是一种针对Unicode的可变长度字符编码;
UTF-8使用一至四个字节为每个字符编码:
&- ASCII字符只需一个字节编码;
&- 拉丁文等 需要二个字节编码;&
&- 其他基本多文种平面(BMP)中的字符三字节编码
&- 其他极少使用的Unicode 辅助平面的字符使用四字节编码
Unicode和UTF-8之间的转换关系表&
& & & & &UCS-4编码 & & & & & UTF-8字节流&
U+ – U+xxxxxxx&
U+ – U+000007FF 110xxxxx 10xxxxxx&
U+ – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx&
U+ – U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
16bit Unicode Transformation Format,把Unicode的码位转换为16比特长的码元;
UTF-16是UCS-2的父集,在BMP中,UTF-16编码就等于UCS码;
在辅助平面中,UTF-16使用“代理对”的方法进行编码;
代理对编码方法:
& 1.码位减去0x10000, 得到的值的范围为20比特长的0..0xFFFFF.&
& 2.高位的10比特值加上0xD800,得到高位代理(范围0xD800..0xDBFF);
& 3.低位的10比特值加上0xDC00,得到低位代理(范围0xDC00..0xDFFF);
高位代理、低位代理、BMP中的有效字符的码位,三者互不重叠;
& - 不同平台使用不同字节序;
& - 为了确定UTF-16文件的大小尾序,在采用UTF-16编码文件的开头,都会放置BOM(Byte Order Mark)信息,FF FE代表UTF-16LE,FE FF代表UTF-16BE;
& - U+FEFF,U+FFFE字符在UNICODE中代表的意义是ZERO WIDTH NO-BREAK SPACE,它是个没有宽度也没有断字的空白;
& - U+6731,UTF-16LE编码为“31 67”,UTF-16BE编码为“67 31”;&
American Standard Code for Information 美国信息交换标准代码;
单字节编码,使用7位二进制数表示,编码范围为0 - 127,可表达128个字符;
ASCII码字符不存在乱码问题,因为绝大部分地区编码都兼容ascii;
扩展ASCII:
标准ASCII码只用到一个字节中的7位,如果使用第8位,则可扩展编码范围128 - 255,扩展后的标准即为ISO8859-1,也称为&Latin-1
4. ISO8859
- ISO 8859,全称ISO/IEC 8859,是一个8位字符集的标准,现时定义了15个字符集
- ASCII收录了空格及94个“可印刷字符”,足以给英语使用。但是,其他使用拉丁字母的语言(主要是欧洲国家的语言),都有一定数量的附加符号字母,故可以使用ASCII及控制字符以外的区域来储存及表示。
- 兼容ASCII,0x20 - 0x7F为ASCII,0xA0-0xFF为ISO 8859-x字符
- Unicode 0x00-0xFF范围的字符由 0x00-0x7F(ASCII) + 0x80-0x9F(控制符) + 0xA0-0xFF(ISO 8859-1)组成
各种ISO 8859字符集&
ISO/IEC 8859-1 (Latin-1) - 西欧语言&
ISO/IEC 8859-2 (Latin-2) - 中欧语言&
ISO/IEC 8859-3 (Latin-3) - 南欧语言。世界语也可用此字符集显示。&
ISO/IEC 8859-4 (Latin-4) - 北欧语言&
ISO/IEC 8859-5 (Cyrillic) - 斯拉夫语言&
ISO/IEC 8859-6 (Arabic) - 阿拉伯语&
ISO/IEC 8859-7 (Greek) - 希腊语&
ISO/IEC 8859-8 (Hebrew) - 希伯来语(视觉顺序)&
ISO 8859-8-I - 希伯来语(逻辑顺序)&
ISO/IEC 8859-9(Latin-5 或 Turkish)- 它把Latin-1的冰岛语字母换走,加入土耳其语字母。&
ISO/IEC 8859-10(Latin-6 或 Nordic)- 北日耳曼语支,用来代替Latin-4。&
ISO/IEC 8859-11 (Thai) - 泰语,从泰国的 TIS620 标准字集演化而来。&
ISO/IEC 8859-13(Latin-7 或 Baltic Rim)- 波罗的语族&
ISO/IEC 8859-14(Latin-8 或 Celtic)- 凯尔特语族&
ISO/IEC 8859-15 (Latin-9) - 西欧语言,加入Latin-1欠缺的芬兰语字母和大写法语重音字母,以及欧元(EUR)符号。&
ISO/IEC 8859-16 (Latin-10) - 东南欧语言。主要供罗马尼亚语使用,并加入欧元符号。&
由于英语没有任何重音字母(不计外来词),故可使用以上十五个字集中的任何一个来表示。
代码页(Code Page),也称“内码表”,是特定语言的字符集的一张表;
早期,字符集编码信息存放在ROM中,被称为OEM代码页(IBM PC使用);
微软针对不同的使用地区与国家,定义了一系列的支持不同语言字符集的代码页,被称作&Windows (或ANSI) 代码页&;
不同的厂商对同一个字符集编码使用各自不同的名称。例如,UTF-8在IBM称作代码页1208, 在微软称作代码页65001, 在SAP称作代码页4110;
微软系统中,中日韩语言代码页:
932 — 日文 (Shift-JIS)
936 — 简体中文(GBK)&
949 — 韩文 (EUC-KR)
950 — 繁体中文(Big5)
GB-x:简体中文编码
中华人民共和国国家标准简体中文字符集,共收录6763个汉字,覆盖中国大陆99.75%的使用频率
对于人名、古汉语等方面出现的罕用字,GB 2312不能处理每个汉字及符号以两个字节来表示,兼容ASCII
Unicode BMP平面汉字。1993年,Unicode 1.1版本推出,收录中国大陆、台湾、日本及韩国通用字符集的汉字,总共有20,902个。
中国大陆将之定为GB13000
汉字内码扩展规范,K为汉语拼音 Kuo Zhan(扩展)中“扩”字的声母
相当于GB 2312 + GB 13000。由于GB 2312-80只收录6763个汉字,有不少汉字并未有收录在内,于是厂商微软利用GB 2312-80未使用的编码空间,收录GB全部字符制定了GBK编码字符有一字节和双字节编码。对于单字节,00–7F范围即ASCII,对于双字节,第一字节的范围是81–FE,第二字节的范围在40–7E及80–FE
国家标准GB 《信息技术 中文编码字符集》,是中华人民共和国现时最新的内码字集
与GB 完全兼容,与GBK基本兼容,支持GB 13000及Unicode的全部统一汉字,共收录汉字70244个
Big5:繁体中文编码
Big5,又称为大五码或五大码,繁体中文地区中最常用的汉字字符集,共收录13,060个汉字
双字节字符集,“高位字节”使用了0xA1-0xF9,“低位字节”使用了0x40-0x7E,及0xA1-0xFE (CP950)
由于很多日常用字未被收录(“着”,“柏”,“喆”等),所以在市面上支持Big5码的软件(如仓颉输入法),有不少都自行在原本的编码外,添加一些符号及用字
如何知道当前字符是何种编码?
不同代码页使用的代码范围不一样,通过检测代码范围来得到一个字符可能的编码。
注意,中日韩等象形文字的编码范围有可能会有重叠部分,因此某个字符检测可能得到多个结果。
如果是判断某个字符串,则可检测每个字符可能的编码,对每一个结果进行与操作,则可得到更准确的结果。
编码 & & & & &范围(只有部分信息,实际请参考代码页)
Shift-JIS & & 高位字节0x81-0xFC,低位字节0x40-0x7E,…,0x -0xFC,
GBK & & & & & 高位字节0x81-0xFE,低位字节0x40-0x7E,0x80-0xFE
Big5 & & & & &高位字节0xA1-0xF9,低位字节0x40-0x7E,0xA1-0xFE
EUC-KR & & & &高位字节0x81-0xFD,低位字节0x41-0x5A,0x61-0x7A,0x81-0xFE
注意编码范围不是连续的,因此在实现过程中,需要根据代码页把其所有范围列出来,检测编码时判断字符是否在该范围
Android使用:http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/
GBK编码范围
ICU:International Components for Unicode, &Unicode国际化组件;
:http://site.icu-project.org/
开源软件,有两种版本:ICU4J(Java)和ICU4C(C,C++)
ICU主要功能:
& 代码页转换
& 字符比较器(Collation)
& 日期,时间,货币,数字等格式转换
& 时区计算
& Unicode支持
& 正则表达式
& 处理文本排向(Bidi )
& 文本边界
ICU提供一个转换器,可以将代码页编码(如GBK)转换成Unicode编码
同一种编码可能有多个别名,创建转换器时可以输入别名
转换器别名信息可从android源码中获取,路径为: android/external/icu4c/data/mappings/convrtrs.txt&
或者从查看Demo: http://demo.icu-project.org/icu-bin/convexp
使用ICU4C完成不同编码的转换
1.创建转换器
convDest = ucnv_open(name,…); //目标转换器,打开转换器如”GBK”,”UTF-8”,返回converter对象
convSrc = ucnv_open(name,…); &//源转换器
ucnv_convertEX(convDest,convSrc,pDest,pDestLen,pSrc,pSrcLen,…)
3.关闭转换器
ucnv_close(convDest);
ucnv_close(convSrc);
了解了字符编码相关知识后,再来看乱码现象。
目前智能手机,平板等设备基本使用unicode字符集,对于unicode字符,可以正常显示,而非unicode字符则需要先转换成unicode,否则会显示乱码。
在转换之前,需要检测编码。由于中日韩文字的编码有重叠部分,检测时有可能得到多个结果,因此在检测结果上还要加个条件,即根据当前设置的语言来决定最终结果。
所以如果设置当前语言为简体中文,查看繁体中文或日韩文编码信息的歌曲时会看到乱码。
抛开效率问题,这种情况其实可以解决,通过判断检测结果是否唯一,如果是则将对应编码转换成utf8即可。
有些mp3歌曲信息是unicode编码,所以无论设置哪种语言都可以显示正确。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:85464次
积分:1023
积分:1023
排名:千里之外
原创:26篇
评论:23条
(1)(1)(6)(3)(1)(2)(3)(1)(5)(2)(2)}

我要回帖

更多关于 java 字符串中文乱码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信