关于Python3编码问题的简单理解(实战,以hashlib为例)

本文详细解析了Python3中字符串和二进制数据流的区别,重点介绍了str和bytes类型的转换方法,以及如何正确使用hashlib库进行数据摘要算法处理,包括MD5和SHA1等常见算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。

这里理解:

str类型是Python的一种数据类型,当你需要使用其他库或与其它程序联用时,往往需要使用二进制数进行信息传递。

除了本文要介绍的hashlib外,如果没有使用二进制数进行信息传递,当你在写网页返回值时,也会报错,如

def run_server(environ):
	# 返回的内容
	# return ['<h1>hello, show a web</h1>',] # 这样会报错
	return ['<h1>hello, show a web</h1>'.encode('utf-8'),]

 

好,我们开始从hashlib入手

hashlib 简介:Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等,它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。

 

import hashlib

def test_hashlib():
    md5obj = hashlib.md5()
    md5obj.update('this is a string')
    rst = md5obj.hexdigest()
    print(rst)  # 9912912bd6c6d2a257cbcf8430f6fc61

	TypeError: Unicode-objects must be encoded before hashing

如果你像上面这么写,会直接报错:


    TypeError: Unicode-objects must be encoded before hashing

原因在于hashlib的方法update只接收字节编码类型

那么,我们可以通过以下3中方式进行编码,解决问题:

def test_hashlib():
    md5obj = hashlib.md5()
    md5obj.update(b'this is a string')    # 方法一
    # md5obj.update('this is a string.'.encode('utf-8'))    # 方法二
    # md5obj.update(bytes('this is a string.', encoding='utf-8'))    # 方法三
    rst = md5obj.hexdigest()
    print(rst)  # 9912912bd6c6d2a257cbcf8430f6fc61

但考虑到我的系统环境编码为 utf-8,那么在方法二的基础上可以这么写:

def test_hashlib():
    md5obj = hashlib.md5()
    md5obj.update(b'this is a string')    # 方法一
    # md5obj.update('this is a string.'.encode('utf-8'))    # 方法二
    # md5obj.update('this is a string.'.encode())    # 方法四
    # md5obj.update(bytes('this is a string.', encoding='utf-8'))    # 方法三
    rst = md5obj.hexdigest()
    print(rst)  # 9912912bd6c6d2a257cbcf8430f6fc61

可以理解为,你在编译器输入的字符串 'this is a string',这是使用utf-8编码的Python内置str型数据,而hashlib不认识str型数据,它只接收字节流,那么我们就要把utf-8 编码的  'this is a string' 字符串编码为字节流,而系统默认是utf-8编码,你可以不指名用什么进行编码。

 

当然,为了测试,我们可以把系统默认的utf-8编码的字符串,转为gbk字符串,然后再转为字符型

为方法五

def test_hashlib():
    md5obj = hashlib.md5()
    md5obj.update(b'this is a string')    # 方法一
    # md5obj.update('this is a string.'.encode('utf-8'))    # 方法二
    # md5obj.update('this is a string.'.encode())    # 方法四
    # md5obj.update(bytes('this is a string.', encoding='utf-8'))    # 方法三
    # md5obj.update('this is a string.'.encode('utf-8').decode('gbk').encode('gbk'))    # 方法五
    # md5obj.update('this is a string.'.encode('').decode('gbk').encode('gbk').decode().encode())    # 方法六
    rst = md5obj.hexdigest()
    print(rst)  # 9912912bd6c6d2a257cbcf8430f6fc61

方法六可以理解为再把二进制数据(字节型)数据转为系统默认编码(utf-8),然后再转为字节型数据

总结:

所有编码类型转换,都需要先转为字节型,然后再转为你想要的编码

utf-8字符串 ------encode------>   bytes类型    -----decode-----> 你想要的编码类型

 

希望对大家有帮助,如果有描述不清楚的地方请多多批评指正 ^^

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值