1、Unicode和UTF-8
(1)Unicode是一种编码方式,把世界上所有的语言都实现了编码,如果直接应用在计算机上会导致极大的空间浪费,而utf-8解决了此中问题,所以得到了广泛的应用。
(2)utf-8是Unicode的一种实现,两者的编码在二进制上并不相同,具体见参考1中的链接。
(3)utf-8最大的特点就是它是一种变长的编码方式,它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
(4)中文的GB2312也是一种中文的编码方式,但是与utf-8和unicode没有任何关系。
2、Python3 中的编码方式
(1)"The default encoding for Python source code is UTF-8, so you can simply include a Unicode character in a string literal". python3源码文件的默认编码方式是UTF-8,所以在python3的源码文件中可以直接使用所有的Unicode字符串,例如:
répertoire = "/tmp/records.log"
with open(répertoire, "w") as f:
f.write("test\n")
print(len('❤️️'))
print(len('🌟'))
(2)UTF-8编码方式便于字符的存储和传输,但是在不同语言的内存中一般不使用UTF-8编码编码(据说:Go语言就是内部用utf8),原因是效率问题。在python3的内存中用的是unicode编码方式:
print("\N{BLACK CHESS KNIGHT}".encode())
str = '♞'
print(str.encode())
s = string_at(id(str), sys.getsizeof(str))
print(sys.getsizeof(str))
print(s.hex())
执行结果是:
b'\xe2\x99\x9e'
b'\xe2\x99\x9e'
76
0300000000000000408e9a08010000000100000000000000e245496c87c29da1a80000000000000000000000000000000000000000000000000000000000000000000000000000005e260000
分析:上述代码中"\N{BLACK CHESS KNIGHT}"和'♞'是同一个Unicode字符
打印结果的第一行和第二行的打印结果都是上述字符的UTF-8编码值,第三行是str对象所占用的字节数(python中一切皆为对象,所以此处的字符串对象长度为76个字节),第三行是str对象在内存中的存储情况在靠近尾部的位置可以找到'♞'的存储值为'5e26',和下图中Unicode编码对照表中的值是相同的,只不过内存中的值是小端存储,所以可以确定python3内存中字符是用unicode编码的。Java内存中字符的表现形式也是Unicode编码。
0061 'a'; LATIN SMALL LETTER A
0062 'b'; LATIN SMALL LETTER B
0063 'c'; LATIN SMALL LETTER C
...
007B '{'; LEFT CURLY BRACKET
...
2167 'Ⅷ'; ROMAN NUMERAL EIGHT
2168 'Ⅸ'; ROMAN NUMERAL NINE
...
265E '♞'; BLACK CHESS KNIGHT
265F '♟'; BLACK CHESS PAWN
...
1F600 '😀'; GRINNING FACE
1F609 '😉'; WINKING FACE
...
查看系统大小端的方法:
if (ByteOrder.nativeOrder()==ByteOrder.BIG_ENDIAN){
System.out.println("big endian");
}else {
System.out.println("little endian");
}
3、Python3 encode和decode方法:Built-in Types
bytes.decode:把指定编码方式(默认是utf-8)的二进制序列解码为Unicode字符。其参数为bytes二进制序列的编码方式---知道其编码方式才能解码
str.encode:把python中Unicode字符转化为指定的编码,默认是utf-8。其参数是要实现的编码方式
#Return a string decoded from the given bytes. Default encoding is 'utf-8'.
bytes.decode(encoding="utf-8", errors="strict")
#Return an encoded version of the string as a bytes object. Default encoding is 'utf-8'.
str.encode(encoding="utf-8", errors="strict")
4、emoji表情符号也是Unicode中的一个符号,与'a','1'等字符相同,而且Unicode字符集也在不断的更新中
emoji及其code point:https://unicode.org/emoji/charts/full-emoji-list.html#1f3f4_e0067_e0062_e0065_e006e_e0067_e007f
UTF-16编码和unicode code point:https://zh.wikipedia.org/wiki/UTF-16
UTF-8编码和unicode code point:https://zh.wikipedia.org/wiki/UTF-8
组合emoji表情符:Unicode: Behind the Curtain
python3 代码,code point转utf-16和utf-8
注:utf-8没有字节序的问题
# code point:U+1F600 emoji:😀
# 注:在mac中实际测试发现\x3d会被替换为=,这里手动做了替换
# 若转化utf-16不指定字节序,则结果中会自带一个字节序:在UTF-16文件的开首,都会放置一个U+FEFF字符作为Byte Order Mark(UTF-16 LE以 FF FE 代表,UTF-16 BE以 FE FF 代表)
>>> '\U0001f600'.encode(encoding="utf-16")
b'\xff\xfe\x3d\xd8\x00\xde'
>>> '\U0001f600'.encode(encoding="utf-16be")
b'\xd8\x3d\xde\x00'
>>> '\U0001f600'.encode(encoding="utf-16le")
b'\x3d\xd8\x00\xde'
>>> '\U0001f600'.encode(encoding="utf-8")
b'\xf0\x9f\x98\x80'
>>>
5、code point(码位) 和 code unit(码元)
(1)code point
(2)code unit
6、参考:
(3)Unicode Character Categories