【擦,终于搞明白了utf8和unicode】

本文以通俗易懂的方式讲解了utf8和unicode的区别,揭示了它们在编程中的角色,包括unicode作为全球文字的统一编码标准,而utf8则是为了解决不同文字字符存储效率问题的可变长度编码。通过实例代码演示,帮助读者消除困惑。
摘要由CSDN通过智能技术生成

背景

今天周六,在家无聊。准备研究一个以前自己半懂不懂的问题,这个utf8和unicode究竟是啥?查了一下午的网上资料,给我脑袋看炸了。什么乱七八糟的,有的说的很有道理,有的越说越糊涂,好像多么高深似的,非要把人弄的兴趣全无。为了解释一个东西,就新造一个新的术语。简直是xxx。

好了,吐槽完毕,言归正传,为了帮助大家简单且深刻的理解一下utf8和unicode,我下面将争取用最朴实的语言来描述,有不到位的地方,希望大家多多评论,一起学习,多谢各位。

  • 示例语言:go
  • 版本:1.18

哎,怎么不一样?

咱想看一下 “韭” 这个字中内存怎么存的。代码如下

var s = "韭"
for i:=0;i<len(s);i++{
	// %x 表示输出16进制
	fmt.Printf("0x%x ",s[i])
}

输出结果为:

0xe9 0x9f 0xad 

不都说,go是直接用utf8编码的吗?我这输出的应该就是"韭"字的utf8编码吧。去找个在线转换软件试试。
试试情况如下:
在这里插入图片描述
好奇怪,这怎么不一样,一个是0xe9 0x9f 0xad,一个是&#x97ED。这在线转换工具,转换出了个啥啊这是?怎么不一样啊。

原来是它

经过查阅多方资料,上面转换出来的&#x97ED 其实是unicode字符。对于unicode,我一直是熟悉且陌生的,很惭愧,干编程工作这么多年。这个最基本的还没完全弄懂。

unicode

为啥会存在这个unicode

计算机专家想把全世界的语言文字都能够在计算机中显示出来。你不可能直接简单的把"韭"字直接塞进计算机吧。对吧,得找个数字来表示"韭"字。

就类似于什么?你在学校里面的学号。比如,张三学号是38号。就是这么个意思,这个数字38就代表张三,就是张三在学校里面的unicode码。

因为全世界的文字是非常多的,有英文,中文,日文,韩文。你看看,单单东亚及这么多文字。

你不可能一个地方一个标准,比如1在亚洲表示中文"我"字,在非洲表示另外一种文字,那不就彻底乱套了。

所以,这个时候统一的标准就来了,这就是unicode。在这套标准下面。假设,"韭"字的学号在北极的电脑是38号,那么在南极也是38号。全球统一。

utf8

我们上面搞明白了unicode,那么这个utf8又是个啥玩意,我不是已经解决了全球各种文字在计算机中存储形式了吗?

这么想是有道理的。

但是我们再回过头来看看,unicode保存了全球的文字,那就有一个什么问题?忒大了。
英文字母也就26个,但是汉字多少个,反正几万个是有的,常用的也有几千个。英文字母26个,一个字节完全能够放的下,但是1个字节存汉字肯定不够,因为一个字节是8个bit位,最多能表示255种数。

查阅资料得知,有的文字在unicode甚至用到了4个字节长度的数。

那要是直接把unicode直接存内存,都用4个字节存,对于有些文字来说就非常浪费了,完全用不上。

所以,这个时候,utf8就诞生了,utf8长度是可变的。

小结

到此为止,我们终于搞清楚了utf8和unicode的对应关系。

unicode是文字的学号(专业一点叫码点,但是此处不想再引入新的名词,浪费时间,浪费兴趣,毫无意义,大家了解即可),所以每一个文字在unicode中都唯一对应一个学号。

utf8是文字实际存储在内存中的样子。

相关go代码

对于上面一开始的问题,其实是网站的问题,网站所谓的utf8其实是unicode编码。

func main() {
	var s = "韭"
	for i := 0; i < len(s); i++ {
		// 这里打印的utf8编码
		fmt.Printf("0x%x ", s[i])
	}
	fmt.Println()

	for _, i := range s {
		// 这里打印的是unicode
		fmt.Printf("0x%x ", i)
	}
	fmt.Println()

	encodeRune()

	decodeRune()
}

// rune -> []byte
func encodeRune() {
	// "韭"字的unicode编码
	var r rune = 0x97ed
	fmt.Printf("the unicode charactor is %c\n", r) // 中
	buf := make([]byte, 3)
	// 编码成utf8
	_ = utf8.EncodeRune(buf, r)                       // 对rune进行utf-8编码
	fmt.Printf("utf-8 representation is 0x%X\n", buf) //
}

// []byte -> rune
func decodeRune() {
	// utf8
	var buf = []byte{0xe9, 0x9f, 0xad}
	// 解码成unicode
	r, _ := utf8.DecodeRune(buf)                                                             // 对buf进行utf-8解码
	fmt.Printf("the unicode charactor after decoding [0xe9, 0x9f, 0xad] is %s\n", string(r)) // 中
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值