你不知道的 字符集和编码(编码字符集与字符集编码)

我的上篇文章,有朋友提出字符集和编码的区别,我在此立文和大家讨论下

常说的字符集和编码区别,其实就是编码字符集和字符集编码的区别,其实,单单如果只是说字符集,没有任何编码的概念的话,那么字符集其实仅仅是一个简单的字符的集合,或者说是一个抽象的字符的集合,包括文字,符号等等,不参与任何存储形式,只是存在这么各种各样标准的字符的集合

如果仅仅是抽象的字符集,我们是无需拿出讨论的,因为没有任何异议,通俗易懂,而常说的字符集指的编码字符集,比如常见的 unicode、ascii、gb2312、gbk等,这些我们常称做为字符集(其实是编码字符集),这些字符集,比如unicode其实本质上是已经“编码”过的字符集,即每个字符都有唯一的整数编号,每个字符都有自己特有的编号,同一个字符在不同编码字符集中编号也会不同,当然很多编码字符集都是ascll的超集,所以ascll字符集的编号与很多编码字符集中编号都一样,比如英文字母“A”,在ASCII及Unicode及GB2312中,均是第0x41个字符,说到这里朋友一定注意到了我上面再描述“ unicode其实本质上是已经“编码”过的字符集”中的“编码”二字加了双引号,我要强调的是这里的“编码”并不是真的我下面要说的编码,这里只是为每个字符编了一个对应的编号,但是我们还是习惯专业的称呼为“编码字符集”

我们经常说“文章采用的是utf-8编码方式”

我对于这个编码方式的意义,个人理解是 将一个字符的整数编号用一个什么二进制的整数值来对应并在计算机存储这和上面说的编码字符集中的“编码”千差万别,这里我们称之为“字符集编码”,即我们常说的编码

说到这里,很多人会觉得那么unicode和utf-8的区别在哪里?既然上文说到unicode是编码字符集,那么utf-8又是什么?就是常说的编码?

“文章采用的是utf-8编码方式”,个人觉得准确的说法是“文章采用的是基于unicode编码字符集的utf-8的编码方案”,即

即unicode本身作为编码字符集没有任何存储形式,只是一个编号和字符对应的表而已,如何在计算机存储?你可能想到了干脆直接把编号当作二进制数值来直接存储,那么为什么不这么做呢?这也算是一种字符集编码方案,就是基于unicode编码字符集的utf-32编码方案,那么有没有更加智能一点的编码方案呢?为什么会没有呢?那就是utf-8、utf-16等等,    等等,在我解释为何要用utf-8编码方案的时候,我必须说明一件事情:如下

我在上一篇文章《你不知道的 页面编码,浏览器选择编码,get,post各种乱码由来》中说过:“如何查看中文字符的十六进制字符串?方法:BitConverter.ToString(System.Text.Encoding.UTF8.GetBytes("阿道夫"));” 请注意我可以改为“System.Text.Encoding.Unicode.GetBytes” 如下图是vs2013 Encoding键入“.”后的智能提示

  (列表过长,用两幅图分别截图)

上图有两个疑问:

1、如果说unicode是编码字符集,为何会出现在和utf-8这种编码方案并列的列表中?

2、ASCII或者gb2312都是编码字符集为何也会出现在和utf-8这种编码方案并列的列表中?

我们假设有两个猜测:

1、此处的unicode并不是真正的unicode编码字符集,可能只是一种和unicode编码字符集关系非常紧密的一种编码方案

2、ASCII或者gb2312(其实就是图中的Default,即操作系统当前的编码,国内一般为gb2312)是编码字符集没有错,但是对于ASCII或者gb2312都只有唯一一种编码,那么我称呼它们为ASCII编码或者GB2312编码也没有问题,既然这样,那我把ascii和gb2312加入和utf-8这种编码方案并列的列表中也理所当然?

我的两个假设,很快得到论证

1、在Encoding 的元数据看到:

1         //
2         // 摘要:
3         //     获取使用 Little-Endian 字节顺序的 UTF-16 格式的编码。
4         //
5         // 返回结果:
6         //     使用 Little-Endian 字节顺序的 UTF-16 格式的编码。
7         public static Encoding Unicode { get; }

这里解释在这里的unicode其实本质上“获取使用 Little-Endian 字节顺序的 UTF-16 格式的编码”,即使基于unicode编码字符集的utf-16编码方案,类似的有BigEndianUnicode(获取使用 Big Endian 字节顺序的 UTF-16 格式的编码)
2、一般的ASCII或者gb2312,我们可以称呼为ASCII字符集也可以称呼为ASCII编码,只是意义不同而已,因为对于ASCII编码字符集或者gb2312编码字符集都只有唯一一种编码,就是ASCII编码和GB2312编码,那么列表中显示的ASCII和GB2312指的不是编码字符集而是ASCII和GB2312的编码方案,我想正是这种原因,才在很多时候,不管是字符集赋值还是编码方案赋值都可以直接用gb2312或者ascii,比如:
Encoding gb2312 = Encoding.GetEncoding("gb2312");
Response.ContentEncoding = gb2312;//编码
Response.Charset="gb2312";//字符集

总结下的说:
就是unicode是字符集,不是编码!但是ascii(gb2312)是字符集,这个说法肯定正确,但是我表达为“ascii编码”也不能说大错特错,但是这种说法让人误解,如果一定要说那么就说“ascii编码字符集的编码”

如果理解上面两个假设的论证道理,那么我们继续讨论之前暂停的话题,即“解释为何要用utf-8等编码方案(其他utf编码方案类似)”
utf-8将很大一部分基于unicode编码字符集的字符的整数编号作了变换后存储在计算机中。(引用)以“汉”字为例,“汉”的Unicode值为0x6C49,但其编码为UTF-8格式后的值为0xE6B189(注意到变成了三个字节)。对于UTF-16编码方案,则是对unicode编码字符集中的前65536个字符编号都不做变换,直接作为计算机存储时使用的值(对65536以后的字符,仍然要做变换),例如“汉”字的Unicode编号为0x6C49,那么经过UTF-16编码后存储在计算机上时,它的表示仍为0x6C49,对于UTF-32编码方案,他对所有的Unicode字符均不做变换,直接使用编号存储,只是这种编码方案太浪费存储空间(就连1个字节就可以搞定的英文字符,它都必须使用4个字节)

既然unicode编码字符集有如此多的编码方案,那么
utf-8,字母数字符号等占1字节,汉字占三字节
utf-16,对unicode编码字符集中的前65536个字符都占两个字节
utf-32,全部占四字节

如果还有人问:
“unicode编码每个字符占几个字节”,我们可以理直气壮的说,第一unicode不是编码!第二每个字符具体占多少字节是要看编码方案!

很多面试题会问:

1 string param = "abc阿道夫";
2 int length1 = System.Text.Encoding.Unicode.GetBytes(param).Length;//别忘了这里的unicode本质是utf-16编码方案
3 int length2 = param.Length;

那么答案就是12和6了

最后,对于gb2312或者ascii编码字符集的字符的编号就是直接存储在计算机中的二进制数,也就是说gb2312和ascii编码字符集都只有一种编码方案,因为在gb2312编码字符集中的ascii字符集部分的编号并没有变化(即和ascii编码字符集中的编码一致),所以gb2312的ascii部分字符存入计算机的二进制数还是占用1个字节,而中文字符存入计算机的二进制数也是该中文字符在gb2312编码字符集中的编号,该编号一般转换成二进制数都占两个字节,这个过程也就变成了所谓的gb2312编码
如果上面的改为System.Text.Encoding.Default.GetBytes(param).Length,则值就是9和6了

如果需要了解更加深入的编码内部原理请参考:
http://blog.csdn.net/nodeathphoenix/article/details/7057760

 

转载于:https://www.cnblogs.com/yinhaichao/p/4090802.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/472806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 数组及多维数组

注意一点,数组每行可以不等长可以两种写法,直接枚举初始化,或者new type [len1][len2]... import java.util.Arrays;public class Myarray {public static void main(String[] args){// 一维数组声明int arr1 [] new int[3];int [] arr2 {…

迷宫搜索问题最短路_【算法常用模板】总结(更新中)

搜索类图类排序类并查集数学类位运算Part1 搜索类bfs 求迷宫问题最短路径(未验证)#include#includeusing namespace std;//用于遍历的结构 (可以添加题目所要求的信息)typedef struct Node{int x,y;int step;}NODE;const int NUM 100; //地图最大范围,根据要求具体…

hook 监控文件 c++_技术分享 | Linux 入侵检测中的进程创建监控

作者简介:张博,网易高级信息安全工程师。0x00 简介在入侵检测的过程中,进程创建监控是必不可少的一点,因为攻击者的绝大多数攻击行为都是以进程的方式呈现,所以及时获取到新进程创建的信息能帮助我们快速地定位攻击行为…

caffe模型文件解析_Caffe ImageData神经网络基本示例无法解析模型文件

我正在尝试使用我使用caffe库从CSV文件准备的 **_图像数据_** 构建神经网络的最小示例。I am trying to build a minimal example of a neural network with **_IMAGE DATA_** that I have prepared from a CSV file using the caffe libraries.我的原始文本如下:\[…

付忠庆的练习小笔记-Codeforces #277 Div2 C

原题链接 http://codeforces.com/contest/486/problem/C 这个C题显然更水一些 步数可以分为两种 上下一种 左右一种 总步数最小 上下最小左右最小 先讨论上下最小 就是从两个方向去由字母1到字母2 min(dis(A,B),26-dis(A,B)); 然后讨论左右最小 pos是起始指针的位置 1-统一在…

Java 类的封装、继承、多态

// 封装、继承、多态 class Person1{String name;int age;private int height;// 私有 封装public Person1(String name, int age){this.name name;this.age age;}public void talk(){System.out.println("This is father class talk() !");}public void setHeight…

hive 创建表_2min快速了解,Hive内部表和外部表

在了解内部表和外部表区别前,我们需要先了解一下Hive架构 :大家可以简单看一下这个架构图,我介绍其中要点:Hive的数据分为两种,一种为普通数据,一种为元数据。元数据存储着表的基本信息,增删改查…

C#微信公众号开发系列教程二(新手接入指南)

此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可直接跳过,也欢迎大神吐槽。 微信公众号开发系列教程一(调试环境部署) 微信公众…

oracle增加字段为主键自增_在 Oracle 中设置自增列

如果你经常使用 MySQL,你肯定对 AUTO_INCREMENT 非常熟悉,因为经常要用到它。一、什么是自增列 ?自增列是数据库中值随插入的每个行自动增加的一列。它最常用于主键或 ID 字段,这样每次增加一行时,不用指该字段的值&am…

Java 抽象类、接口

abstract class 抽象类定义规则如下: (1) 抽象类和抽象方法都必须用 abstract 关键字来修饰。 (2) 抽象类不能被直接实例化,也就是不能用new关键字去产生对象。 (3) 抽象方法只需声明,而不需实现。 (4) 含有抽象方法的类必须被声明为抽象类&#xff0c…

fastdfs windows部署_Go在windows下编译Linux可执行文件

欢迎关注我的头条号:Wooola,专注于Java、Golang、微服务架构,致力于每天分享原创文章、快乐编码和开源技术。前言最近楼主做了一个滑块验证码登录功能,但有个问题,悲观估计一天大约会产生两百多G临时图片放在fastdfs文…

python按索引删除字符串,基于特定的索引字符串值选择记录,然后通过python删除后续字段...

I have a .csv file named file01.csv that contains many records. Some records are required and some are not. I find that the required records has a string variable “Mi”, but it is not exist into the unnecessary records. So, I want to select the required r…

我们并没有觉得MapReduce速度慢,直到Spark出现

learn from 从0开始学大数据(极客时间) Spark 拥有更快的执行速度 更友好的编程接口 迅速抢占 MapReduce 的市场份额,成为主流的大数据计算框架 val textFile sc.textFile("hdfs://...") // 根据 HDFS 路径生成一个输入数据 RDD v…

python远程调用摄像头_Python设置Socket代理及实现远程摄像头控制的例子

为python设置socket代理首先,你得下载SocksiPy这个.解压出来之后里面会有一个socks.py文件.然后你可以把这个文件复制到python安装目录里面的Lib\site-packages中.或者把这个文件复制到程序所在的目录中. 然后就可以再程序中使用socket代理来编写程序了. 下面是示例代码 import…

基于ArcEngine与C#的鹰眼地图实现

鹰眼图是对全局地图的一种概略表达,具有与全局地图的空间参考和空间范围。为了更好起到空间提示和导航作用,有些还具备全局地图中重要地理要素,如主要河流、道路等的概略表达。通过两个axMapControl控件,主控件axMapControl 1和鹰…

LeetCode 1178. 猜字谜(状态压缩+枚举二进制子集+哈希)

文章目录1. 题目2. 解题1. 题目 外国友人仿照中国字谜设计了一个英文版猜字谜小游戏,请你来猜猜看吧。 字谜的迷面 puzzle 按字符串形式给出,如果一个单词 word 符合下面两个条件,那么它就可以算作谜底: 单词 word 中包含谜面 …

elasticsearch 工作原理_【154期】面试官:你能说说 Elasticsearch 查询数据的工作原理是什么吗?...

点击上方“Java面试题精选”,关注公众号面试刷图,查缺补漏>>号外:往期面试题,10篇为一个单位归置到本公众号菜单栏->面试题,有需要的欢迎翻阅阶段汇总集合:一百期面试题汇总面试题ES 写入数据的工…

php另类上传图片的方法(PHP用Socket上传图片)

服务器端&#xff1a; 。 代码如下:<?phpset_time_limit(10);//* 设置不显示任何错误 *///error_reporting(0); function varinfo($str) {echo "<PRe>";var_dump($str);echo "<pre>";} $commonProtocol getprotobyname("tcp");…

java会被淘汰吗_Java不会被淘汰的12个原因

如今&#xff0c;面对曾经在程序员中被各种新技术掩盖直至堙灭的技术值得怀念。犹如COBOL这当年被老程序员们尊为神器的语言如今也基本没有价值。而Java作为现代程序员的中坚力量在这点上或许会成为下一个COBOL。有关JAVA的技术卖出多少本书已经是一个很久远的记忆了。现处中年…

Java 关于类的专题

文章目录1. Object 类2. 内部类3. 覆写 Object 类的 equals 方法4. 接口对象实例化5. this() 调用无参构造方法6. static 属性所有对象共享一份7. static 方法不能调用 非static 属性8. 静态代码块9. final 关键字10. instanceof 关键字1. Object 类 所有的类都是继承于 Objec…