一段大小端转换代码引出的问题
#python2
"6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000".decode('hex')[::-1].encode('hex_codec')
#=> 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
一个问题让我把字符集(unicode)、编码规则(utf-8)等知识都查了一遍
正文
- unicode与utf-8不同概念,前者为字符集,后者为编码格式
- unicode狭义来说只是一个字符集,而utf-8是编码规则,通俗说UTF-8是Unicode的一种实现方式,Unicode有多种实现方式,还有ucs-2(utf-16)。编码规则才涉及到字节的问题。
- Unicode是字符集,定义每个字符对应的数字。
- UTF-8、UTF-16等是编码格式,定义“字符对应的数字”如何以二进制的方式存储。
- 字符集指的是字符在计算机中的码制标识,而编码格式指字符变成二进制的规则
- 在 Python 2 中,字符串类型默认是二进制编码,而不是 Unicode 编码,Python 3 则相反
#python2
# 字符串是二进制编码
s = 'hello world'
print type(s) # <type 'str'>
# 字符串是 Unicode 编码
u = u'hello world'
print type(u) # <type 'unicode'>
# 将二进制编码的字符串转换为 Unicode 编码的字符串
s = '你好'
u = s.decode('utf-8')
print type(u) # <type 'unicode'>
# 将 Unicode 编码的字符串转换为二进制编码的字符串
u = u'你好'
s = u.encode('utf-8')
print type(s) # <type 'str'>
- 因此python2的decode(),encode()方法和python3中的实际逻辑是相反的
- 在 Python 2 中,由于字符串默认是字节序列,因此需要使用 decode() 方法将其转换为 Unicode 字符串。而在 Python 3 中,字符串默认是 Unicode 字符串,因此需要使用 encode() 方法将其转换为字节序列。
\u
表示的是两个字节的十六进制数,因为Unicode是两个字节长度,\x
表示的是一字节的十六进制数,因为ascii是一个字节长度,\x 表示一个字符转义序列,用于表示一个十六进制数。例如,\x41 表示 ASCII 码中的大写字母 “A”。字符转义序列通常用于字符串中,以表示特定的字符或字节。- Python对bytes类型的数据用带b前缀的单引号或双引号表示
x = b'ABC'
- 在bytes形式的串中,无法显示为ASCII字符的字节,用
\x##
显示。
#python3
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
要注意区分’ABC’和b’ABC’,前者是str,后者虽然内容显示和前者一样,但bytes的每个字符都只占用一个字节。
因此开头那段代码
#python2
"6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000".decode('hex')[::-1].encode('hex_codec')
#=> 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
因为python2中字符串是二进制形式的,因此要用decode()方法转换为十六进制字节串,然后以字节为单位反转,编码
参考链接:
https://zhuanlan.zhihu.com/p/215211039?utm_id=0
https://blog.csdn.net/weixin_49340599/article/details/116142153
https://foofish.net/unicode_utf-8.html
unicode与utf-8不同概念