今天在往oracle数据库里插入数据时发现,往一个20字节的字段里插入8个汉字加上一个括号,并没有提示字段超长。猜想数据库应该并没有用万国码(utf-8)。

查询数据库编码sql:select * from nls_database_parameters where parameter ='NLS_CHARACTERSET';

蹦出来这么一个玩意,是该好好捋一捋的时候了

字节、位的关系

字节(byte) 
二进制位,懂点计算机的都知道,计算机是不认识汉字,字母等等的,它只认识0和1。0和1代表了两种状态,高电平,低电平。。。(这儿不详细叙述),所以位是计算机内部数据储存的最小单位。

位( bit)

字节是计算机中数据处理的基本单位。
字节的标准定义:一个字节均为8位。由于上述所讲每个位或者是0或者是1,所以一个8位的字节包含256种可能的0,1组合。列如,int 占用4(byte),它就占用32位,理论上它能表示2^32,但
是它还需要一个符号位,和一个0。它就只能表示-2^31 ~ 2^31 - 1之间的整数,所以:
int a;
a+1<a;//这种情况是存在的的

GBK编码

前面我们说到,计算机只能识别0和1,那要处理字符和文本怎么处理呢?那就必须先把文本转换为数字才能处理。众所周知,计算机是美国人发明的玩意,他最开始根本就没想过带第三世界的人民玩,最开始的计算机只有8位。八位的字节一共可以组合出256(2的8次方)种不同的状态。他们就把所有的大小写字符、数字、标点符号、空格用连续的字节状态表示。这就是最开始的ASCII码,比如大写字母A的编码是65,

小写字母z的编码是122。后来欧美其他一些国家也加入,就有了从128到255这一页的”扩展字符集“。等到了中国人加入的时候已经没有字符可以使用了,况且中国有十多万汉字,常用汉字都有6000多,我们就

保留了1-127号的字符,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多

个简体汉字了,这就叫做叫做 GB2312。而7000多个汉字显然是不够的,后来在GB2312的基础上进行了扩展,结果扩展之后的编码方案被称为 GBK 标准。所以这里一个汉字算两个英文字符,即汉字占用两个字节,英文占用一个字节。

Unicode编码

到这里你可以想象了,中国人自己搞了一套gbk,韩国人搞一套Euc-kr,冲突就不可避免了,这就出现了乱码。这时Unicode(统一码、万国码、单一码)出现了,它将所有的语言符号都包含了进去,unicode统一用两个字节,也就是16位来统一表示所有的字符。所以Unicode中一个字符就是一般的两个字节。

如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001

前面Unicode解决了乱码的问题,但是英语只需要用到8位,高8位永远是0,因为Unicode在保存英文时会多浪费掉一倍的空间,虽然现在硬盘或者内存都很廉价,但是在网络传输中,这个问题就凸显出来了,你可以这样想想,本来1M的带宽在ANSI下可以代表1024*1024个字符,但是在Unicode下却只能代表1024*1024/2个字符。也就是1MB/s的带宽只能等价于512KB/s。为解决unicode如何在网络上传输的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。

但是这样又导致了一个问题,虽然UTF-8可以使用一个字节来表示ANSI下的符号,但是对于其它类似汉语的符号,得需要两个字节来表示,所以计算机不知道如何去截取一个符号,也就是一个符号对应的二进制的截取开始位置和截取结束位置。所以为了解决Unicode下的ANSI符号的空间浪费和网络传输下如何截取字符的问题,UTF规定:如果一个符号只占一个字节,那么这个8位字节的第一位就为0。如果为两个字节,那么规定第一个字节的前两位都为1,然后第一个字节的第三位为0,第二个字节的前两位为10,然后如果是三个字节的话,那么第一个字节的前三位为111,第四位为0,剩余的两个字节的前两位都为10。按照这样的算法去思考一个中文字符的UTF-8是怎么表示的:一个中文字符需要两个字节来表示,两个字节一共是16位,那么UTF-8下,两个字节是不够的,因为两个字节下,第一个字节已经占据了三位:110,然后剩余的一个字节占据了两位:10,现在就只剩下11位,与Unicode下的两个字节,16位去表示任意一个字符是相悖的。所以就使用三个字节去表示非ANSI字符:三个字节下,一共是24位,第一个字节头四位是:1110,后两个字节的前两位都是:10,那么24位-8位=16位,刚好两个字节去表示Unicode下的任意一个非ANSI字符。这也就是为什么UTF-8需要使用三个字节去表示一个非ANSI字符的原因了!

最后在安利点干货:

其中用得最广的utf-8 是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,当字符在ASCII码的范围时,就用一个字节表示,保留了ASCII字符一个字节的编码做为它的一部分,注意的是unicode一个中文字符占2个字节,而UTF-8一个中文字符占3个字节)。从unicode到uft-8并不是直接的对应,而是要过一些算法和规则来转换。

Unicode符号范围 | UTF-8编码方式

(十六进制) | (二进制)
—————————————————————–
0000 0000-0000 007F | 0xxxxxxx

0000 0080-0000 07FF | 110xxxxx 10xxxxxx

0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件:

所以你看到很多网页的源码上会有类似的信息,表示该网页正是用的UTF-8编码。

  题外话:

  然,中国的汉字多达10多万,常用的汉字3500左右[08年统计],如果用3个字节来表示,一共只有2^16(65535)种可能,不足以表示10多万的汉字。所以中日韩的超大字符集是采用的4个字节来表示的,多达6万多个。但是平时使用超大字符集的概率0.01%都不到。所以我们一般认为日常的中文在UTF-8中占三个字节 即可!

多个字节提供的位数超过了所需要的,多余的位以0补全到编码前面

参考:http://blog.chinaunix.net/uid-12014716-id-4152047.html

http://www.cnblogs.com/web21/p/6092414.html

 
 

 

												

Java字符编码的更多相关文章

  1. 【字符编码】Java字符编码详细解答及问题探讨

    一.前言 继上一篇写完字节编码内容后,现在分析在Java中各字符编码的问题,并且由这个问题,也引出了一个更有意思的问题,笔者也还没有找到这个问题的答案.也希望各位园友指点指点. 二.Java字符编码 ...

  2. Java 字符编码归纳总结

    String newStr = new String(oldStr.getBytes(), "UTF-8");       java中的String类是按照unicode进行编码的 ...

  3. 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

  4. 【JAVA编码】 JAVA字符编码系列二:Unicode,ISO-8859,GBK,UTF-8编码及相互转换

    http://blog.csdn.net/qinysong/article/details/1179489 这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记 ...

  5. 【JAVA编码专题】JAVA字符编码系列一:Unicode,GBK,GB2312,UTF-8概念基础

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

  6. Java 字符编码(二)Java 中的编解码

    Java 字符编码(二)Java 中的编解码 java.nio.charset 包中提供了一套处理字符编码的工具类,主要有 Charset.CharsetDecoder.CharsetEncoder. ...

  7. Java 字符编码(三)Reader 中的编解码

    Java 字符编码(三)Reader 中的编解码 我们知道 BufferedReader 可以将字节流转化为字符流,那它是如何编解码的呢? try (BufferedReader reader = n ...

  8. Java 字符编码(一)Unicode 字符编码

    Java 字符编码(一)Unicode 字符编码 Unicode(http://www.unicode.org/versions/#TUS_Latest_Version) 是一个编码方案,说白了希望给 ...

  9. java字符编码详解

    引用自:http://blog.csdn.net/jerry_bj/article/details/5714745 GBK.GB2312.iso-8859-1之间的区别 GB2312,由中华人民共和国 ...

  10. JAVA字符编码三:Java应用中的编码问题

    第三篇:JAVA字符编码系列三:Java应用中的编码问题 这部分采用重用机制,引用一篇文章来完整本部分目标. 来源:  Eceel东西在线 问题研究--字符集编码  地址:http://china.e ...

随机推荐

  1. node-Telnet

    什么是Telnet(window系统) 使用Telnet工具作为客户端对创建的TCP服务器进行会话交流时遇到的问题做一个简单的记录.希望可以帮助到一些同学. 这里看一下百度词条的解释 Telnet协议 ...

  2. vue2购物车ch4-(筛选v-for 点击的那个设置样式 设为默认地址其他 联动 非循环的列表选中和非选中 删除当前选中的列表)

    1 address.html <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  3. ZOJ2185 简单分块 找规律

    初步找大概位置,然后找精确位置,算是简单化的分块吧! #include<cstdio> #include<cstdlib> #include<iostream> u ...

  4. oracle基本查询语句总结

    spool E:\基本查询.txt 将命令行的语句写入到指定的目下的指定的文件中 host cls 清屏命令 show user 显示当前操作的用户 desc emp 查看表结构 select * f ...

  5. WPF DataGrid 样式设置

    隔行换色,鼠标单击,悬浮样式都有,其具体效果如图 1 所示. 图 1 WPF DataGrid 样式设置效果图 其中: 界面设计代码下所示 ? + 查看代码 1 2 3 4 5 6 7 8 9 10 ...

  6. Linux基础命令讲解(一)

    Linux命令基本格式: 命令 [参数] [路径文件] 方括号内容可省略 查看命令帮助手段: 1 man 命令名(man 还可以获取配置文件,函数的帮助) 2 命令 --help 3 help 命令( ...

  7. 架构师必备软件:安装Dubbo注册中心(Zookeeper-3.4.6)

    Dubbo建议使用Zookeeper作为服务的注册中心. http://www.roncoo.com/details?cid=f614343765bc4aac8597c6d8b38f06fd 注册中心 ...

  8. 开始Java8之旅(四) --四大函数接口

    前言   Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词   在学习 ...

  9. 怎么样防止Sql注入

    (1)对于动态构造SQL查询的场合,可以使用下面的技术: 第一:替换单引号,即把所有单独出现的单引号改成两个单引号,防止攻击者修改SQL命令的含义.再来看前面的例子,“SELECT * from Us ...

  10. 文本处理工具(grep)

    文本处理工具:     Linux上文本处理三剑客:        文本过滤工具(模式:pattern)工具:          1.grep:支持基本正则表达式;          2.egrep: ...