• Python进阶——哈希和加密


    哈希函数

    概念

    哈希,英文叫做 hash

    哈希函数(hash function)可以把 任意长度的数据(字节串)计算出一个为固定长度的结果数据。

    原理是把Key通过一个固定的算法函数即所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。


    而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位。
     

    我们习惯把 要计算 的数据称之为 源数据, 计算后的结果数据称之为 哈希值(hash value)或者 摘要(digests)。

    有好几种哈希函数,对应不同的算法, 常见有的 MD5, SHA1, SHA224, SHA256, SHA384, SHA512

    哈希计算的特点是:

    • 相同的 源数据, 采用 相同的哈希算法, 计算出来的哈希值 一定相同

    • 不管 源数据 有多大,相同的哈希算法,计算出来的哈希值长度 都是一样长的。 、

    算法计算结果长度
    MD516字节
    SHA120字节
    SHA22428字节
    SHA25632字节
    SHA38448字节
    SHA51264字节
    • 算法不可逆。

      也就是说,不能通过 哈希值 反过来计算出 源数据。 所以哈希和我们常说的加密解密不同。

    • 不同的源数据 使用同样的哈希算法,可能会产生相同的 哈希值,这被称之为碰撞率(collision rate)

      各种哈希算法,计算的结果长度越长,碰撞率越低,通常耗费的计算时长也越长。

      即使是 MD5 算法, 碰撞率也 非常小,小到几乎可以忽略不计。大约是 1.47*10的负29次方


    应用场景

    那么哈希函数到底有什么用呢?

    下面是典型的两个应用场景

    校验拷贝下载文件

    大家有过下载大文件吧? 比如下载 一部电影、Windows安装iso文件。

    这些文件传输过程中,由于种种原因,可能会出现传输出错的。

    有的数据文件,只有传错一点,整个文件都是不可用的。

    怎么校验我 下载的文件是不是 毫无差错的呢?

    一段一段 的再去和原来的 数据进行比对? 太慢 太麻烦了。

    这时候,可以使用哈希算法。

    下载的网站上,先提供 源文件的 的 哈希值, 下载完后,在我们的电脑上,把本地下载到的 文件也计算哈希值,如果两者相等,那么就可以认为 下载没有问题。

    校验信息有效性

    如果你经营一个学校,每年开学时,学生要到 管理部 交学费, 一个交完学费,工作人员给他们的手机上发一条信息 张三,学费已交

    张三带着这个手机信息到 教学部 领书, 教学部工作人员,看到手机上 有 张三,学费已交 就给他发书。

    这个流程,有一个问题: 教学部的人 怎么知道 学生已交学费的短信 是不是自己伪造的?

    一种解决方法,就是, 管理部和教学部 共享一个密钥,也就是一串字符串,比如 13ty8ffbs2v ,

    管理部的人,收到费用,并且给学生发的 短信,除了 张三,学费已交 之外, 用哈希算法,对如下字符串进行哈希计算

    张三,学费已交|13ty8ffbs2v
    

    这个字符串里面包含了密钥, 如果使用MD5算法,产生这样的哈希值 ccdcb2e80ee2cbf2520844498e4169b0

    给学生发的短信不仅有 张三,学费已交 ,还要包括哈希值 ccdcb2e80ee2cbf2520844498e4169b0

    到了 教学部, 发书的老师,也使用 哈希算法,对如下字符串进行哈希计算

    张三,学费已交|13ty8ffbs2v
    

    如果计算的结果 和学生提供的短信里面的哈希值一致,说明没有捏造信息。

    注意,密钥 13ty8ffbs2v 只有 教学部 和管理部的老师知道,学生是不知道的。所以学生没有办法产生 管理部们才能制作出来的 哈希值。


    Python语言计算哈希值

    这个网站 提供了哈希值计算功能,大家可以快速得到一个数据的 哈希值。

    那么我们怎么使用Python语言来创建哈希值呢?

    使用 Python 内置库 hashlib 即可。

    比如,我们要产生 MD5 哈希值,就这样写代码

    1. import hashlib
    2. # 使用 md5 算法
    3. m = hashlib.md5()
    4. # 要计算的源数据必须是字节串格式
    5. # 字符串对象需要encode转化为字节串对象
    6. m.update("张三,学费已交|13ty8ffbs2v".encode())
    7. # 产生哈希值对应的bytes对象
    8. resultBytes = m.digest()
    9. # 产生哈希值的十六进制表示
    10. resultHex = m.hexdigest()
    11. print(resultHex)

    结果为 ccdcb2e80ee2cbf2520844498e4169b0 ,这就是哈希字节串的十六进制表示。


    如果你想使用别的哈希算法,比如, sha256 算法,只需要修改为对应的函数 sha256()即可

    如下

    1. import hashlib
    2. m = hashlib.sha256()

    其它都不用变。

    是不是很简单 :)

    关于 hashlib用法的其他细节,可以查看官方文档

    加密解密

    简介

    加解密算法,是对源数据 进行运算产生加密数据,以及反向过程,对加密数据反算出 源数据。

    加解密算法 和 hash算法 不同点有:

    • 加解密算法 是可逆的,hash算法是不可逆的。

    • hash算法可以对很大的数据产生比较小的哈希值,而加密算法源数据很大,加密后的数据也会很大

    加解密算法 可以分为 对称加密 以及 不对称加密

    对称加密 指 加密和解密 使用相同的 密钥 。

    而 不对称加密 指 加密和解密 使用不同的 密钥,通常是一对密钥,称之为公钥(用来加密)和私钥(用来解密)。

    比较常见的 对称加密算法有: AES, RC4, DES, 3DES, IDEA 等。

    其中安全等级较高的是 AES。 关于加密算法安全性可以参考这篇文章

    而最知名的 不对称加密系统 就是 RSA (Rivest–Shamir–Adleman) 。

    Python语言加解密

    计算哈希值, Python有内置的库。

    但是,加解密的库,Python 没有内置的。我们需要安装使用第三方开发的库。

    目前口碑比较好的Python加解密库有 cryptography 和 PyNaCl

    这里,我们以使用比较广泛的 cryptography 为例(Paramiko就使用该库作为底层加解密计算),展示如何进行加解密。

    首先,我们执行命令 pip install cryptography 安装该库。

    注意:由于Paramiko就使用该库作为底层加解密计算,如果你已经安装了Paramiko,cryptography库肯定已经安装好了。 就会显示 Requirement already satisfied

    下面是一个使用 该库进行 AES 加解密运算的例子

    1. from cryptography.fernet import Fernet
    2. # 产生密钥, 密钥是加密解密必须的
    3. key = Fernet.generate_key()
    4. f = Fernet(key)
    5. src = "白月黑羽网站学习Python真好啊"
    6. # 源信息,必须是字节串对象
    7. # 字符串对象需要encode一下
    8. srcBytes = src.encode()
    9. # 生成加密字节串
    10. token = f.encrypt(srcBytes)
    11. print(token)
    12. # 解密,返回值是字节串对象
    13. sb = f.decrypt(token)
    14. print(sb.decode())
  • 相关阅读:
    10 Redis之SB整合Redis+ 高并发问题 + 分布式锁
    区块链技术与人工智能如何相互赋能
    Mit6.006-problemSet01
    React学习笔记(一)
    自动化测试-架构真题(三十)
    Android Framwork知识学习总结
    Typora美化思路分享
    Python封装机制及实现方法
    studio flutter iPhone 真机无法识别
    通过求解数学模型来选择编码节点的最佳数量和位置(Matlab代码实现)
  • 原文地址:https://blog.csdn.net/weixin_47649808/article/details/126329045