碎碎念:
这几天在学习Python对Unicode的支持

上学的时候,计算机基础课上总能听到老师讲什么字节,字符,Unicode,UTF-8吧啦吧啦一堆,反正我是只记住了名字,至于具体这些名字所表达的含义,当时的我是一点也没有想要好好了解的意愿,必竟是一看就会睡着的内容。

那时候心里想的是,老师能不能快点讲一些可以“实战”的东西,这些理论的内容真真太无聊,太无趣了。

啊啊啊,可是,出来混,果真迟早是要还的,那时候没听的讲,现在都要自己补回来,QAQ...


这篇文章主要是模拟Unicode转换UTF8编码的过程,以此来加深对Unicode和UTF8之间关系的理解。

首先明确4个基础概念:

字节: 1字节由8个二进制位组成,是计算机计算存储容量的一个计量单位(1 Byte=8 bit)

字符: 1个符号,由1个或多个字节组成

Unicode(简称UCS ): 编码规则,为每种语言中的每个字符设定了统一并且唯一的二进制编码。
可以将Unicode理解成一个字符数据库,每个字符都与唯一的数字关联,称为code point。这样,英文大写字母A的codepoint是U+0041。而欧元符号的codepoint是U+20A0,其他类似。一个文本字符串就是这样一系列的codepoint,表示字符串中每个字符元素。

UTF-8(Transfer format): Unicode编码规则的具体实现(将code point转换到程序数据的编码方案)

我是这样理解的:字节:单位名称,字符:内容呈现,Unicode:制定规则,UTF-8:规则实现

UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8的编码规则很简单,只有二条:

  • 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
  • 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

    下表总结了编码规则,字母x表示可用编码的位。
Unicode符号范围
(16进制)
UTF-8编码方式
(2进制)
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是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。
然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“严”的UTF-8编码是“11100100 10111000 10100101”,转换成十六进制就是E4B8A5。

脚本主要实现思路

  • 指定一个字符,找到其在Unicode规范中对应的code point。
  • 将code point 转换为10进制
  • 根据上一步得到的10进制数,判断指定的字符需要使用几个字节表示
  • 根据Unicode,utf8转换规则,将步骤2得到的2进制数通过Utf8编码方式重新编码
  • 打印结果(指定字符的utf8编码)

代码:


UnicodeSet={"A":"41","严":"4E25","汉":"6C49","test":"10ffff"}
utf8Set=[] test = "严"
if test in UnicodeSet:
# 将code point 转换为10进制数字 tencode = int(UnicodeSet[test], base=16)
twocode = bin(tencode)[2:] #判断测试字符需要几个字节表示
if 0<= tencode <=127:
codeLevel=1 elif 128 <= tencode <= 2047:
codeLevel = 2 elif 2048 <= tencode <= 65535:
codeLevel = 3 elif 65536 <= tencode <=1114111:
codeLevel = 4
else:
print("超出编码范围") # 按UTF8编码规则对code point 进行编码
if codeLevel == 1:
rescode = twocode
else:
pre = -6
after = len(twocode)
for i in range(codeLevel): singleByte = "10"+twocode[pre:after]
pre = pre - 6
after = after -6 if i == codeLevel-1:
numzero = 8-codeLevel-len(twocode[0:-after])-1
singleByte ="1"*codeLevel+"0"+"0"*numzero+twocode[0:-after]
utf8Set.append(singleByte)
utf8code = "".join(utf8Set[::-1])
rescode = hex(int(utf8code,base=2))[2:] print(f"Unicode定义字符 {test} 的 codepoint为: {UnicodeSet[test]}\
\n 将codepoint转换为utf8编码:{rescode}")

小白的记录帖,不足之处,欢迎指出

版权声明:原创文章,欢迎转载,转载请注明出处 http://www.cnblogs.com/kaerxifa/p/8910024.html

Unicode转换为UTF-8过程Demo的更多相关文章

  1. 扩展ASCII码,不同的国家有不同的字符集。Unicode转换为utf8的规则,utf8没有大小端的问题。超过0xFFFF的Unicode字符WINAPI也无能为力(附各种字符编码表及转换表)good

    一.概念 1,ASCII             ASCII(American Standard Code for Information Interchange),中文名称为美国信息交换标准代码.是 ...

  2. Unicode、UTF-8 和 ISO8859-1

    Unicode.UTF-8 和 ISO8859-1到底有什么区别 1.本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等. 在下面的描述中,将以"中文" ...

  3. Unicode和UTF的关系

    目录结构: contents structure [+] 什么是USC UCS的编码方式 Unicode的来源 为什么需要Unicode Unicode的方式 Unicode和UTF UTF和Unic ...

  4. c#将http调用返回额json中的有关中文的unicode转换为中文

    c#将http调用返回额json中的有关中文的unicode转换为中文 中文转Unicode:HttpUtility.UrlEncodeUnicode(string str);转换后中文格式:&quo ...

  5. unicode转换为中文

    unicode转换为中文 \u5f53\u5730\u65f6\u95f42019\u5e747\u670813\u65e5\uff0c\u82f1\u56fd\u8d1d\u5fb7\u798f\u ...

  6. ASCII、UNICODE、UTF

    在计算机中,一个字节对应8位,每位可以用0或1表示,因此一个字节可以表示256种情况. ascii 美国人用了一个字节中的后7位来表达他们常用的字符,最高位一直是0,这便是ascii码. 因此asci ...

  7. Unicode、UTF-8 和 ISO8859-1到底有什么区别

    说明:本文转载于新浪博客,旨在方便知识总结.原文地址:http://blog.sina.com.cn/s/blog_673c81990100t1lc.html 本文主要包括以下几个方面:编码基本知识, ...

  8. Delphi7中Unicode,ANSI,UTF编码问题

    注解: ANSI     'American Standard Code for Information Interchange' 美国信息互换标准代码 ANSI的'Ascii'编码 Unicode ...

  9. ascii、unicode、utf、gb等编码详解

    很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为"字节".再后来,他们又做了一些可以处理这 ...

随机推荐

  1. noip模拟赛 正方形

    题目描述在一个10000*10000的二维平面上,有n颗糖果.LYK喜欢吃糖果!并且它给自己立了规定,一定要吃其中的至少C颗糖果!事与愿违,LYK只被允许圈出一个正方形,它只能吃在正方形里面的糖果.并 ...

  2. hdu_1213_How Many Tables_201403091126

    How Many Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  3. 相克军_Oracle体系_随堂笔记 PPT

    http://www.cnblogs.com/jyzhao/category/581259.html http://download.csdn.net/detail/yzj149286454/8960 ...

  4. Equals和==的差别

    java中的数据类型.可分为两类:  1.基本数据类型 包含:byte,short,char,int,long,float,double,boolean .基础数据类型比較大小的时候使用的是双等号(= ...

  5. iOS分组通讯录效果+側滑菜单(MMDrawerController)

    前言的废话-能够忽略 自从学会了使用Cocoapod,就欲罢不能了!由于太简单太赞了,不用再把源代码粘到project里了! 參见戴维营博客中的解说:Cocoapod 安装以及使用 先上一下效果图,请 ...

  6. 【安卓笔记】ormlite入门

    ps:写这篇文章的目的是尝试下新的markdown编辑器哈哈 简单介绍 ORMLite provides a lightweight Object Relational Mapping between ...

  7. c++中cin的基本使用方法

    一.最主要的使用方法cin>> 接收一个数字.字符.字符串.遇"空格"."TAB"."回车"都结束 比如: <span s ...

  8. thymeleaf+springboot找不到html,只返回了字符串

    在浏览器用链接http://localhost:8080/city/page/list 访问时页面上只出现了cityList字样,预期是返回cityList.html 解决:在controller中使 ...

  9. Mongo 中间件 pre find 修改query

    需求:在所有find查询的时候,默认添加查询参数 name:bennman //创建一个query中间件 myMid.js module.exports = function(schema){ //这 ...

  10. 正确的缩写document。querySelector

    北京的夕阳,伴随淡淡的霾殇.从写字楼望去,光线是那么昏黄.没有孤雁,也没有霞光,遥想当年,还是 jQuery 独霸一方.那时的我们,写程序都习惯了使用 $,至少在对美元符号的喜爱上,与 PHP 达成了 ...