Python中的哈希算法

2025 年 1 月 5 日 | 阅读 9 分钟

简介

哈希(Hashing)是计算机科学和密码学中的一个关键概念。它指的是对输入数据(也称为消息)应用一个数学函数或算法。这个过程会生成一个固定大小的字符序列,通常是十六进制数字或一串字符,称为哈希值。

  • 输入:任意文本
  • 输出:固定长度文本(哈希值)
Hashing Algorithm in Python

好的哈希函数的属性

  • 不可逆性:对于加密应用来说,很难从给定的输出推导出生成它的输入,这是至关重要的。
  • 固定大小输出:由于无论输入大小如何,它都会生成固定大小的输出,因此更容易比较和存储哈希值。
  • 确定性:哈希函数必须是确定性的,这意味着对于相同的输入,输出应该始终相同。

哈希函数示例

一些流行的哈希函数包括

  • SHA-1
  • SHA-2
  • SHA-3
  • MD5
  • Blake2
  • BLAKE3

Python 中的哈希函数

Python 中的哈希函数可以更简单地从纯文本创建哈希值。

Python 的 `hash()` 函数为对象生成唯一的哈希值(一个固定大小的整数)。此哈希值代表对象的身份,并在各种数据结构和算法(包括集合和字典)中使用,以便快速比较和查找对象。

`hash()` 函数仅适用于特定对象;并非所有对象都可以使用。

`hash()` 函数不能哈希可变对象,如列表、字典和集合。

了解哪些对象可以在 Python 中哈希是很重要的。

可哈希对象

  1. 字符串
  2. 整数(以及其他数值类型,如浮点数和复数)
  3. 元组(如果提供的元素是可哈希的)
  4. 冻结集合
  5. 字节和字节数组
  6. 具有正确实现 `__hash__()` 方法的自定义对象。
  7. 不可变内置类型包括布尔值、`NoneType` 以及 `True`、`False` 和 `None` 等常量。

不可哈希对象

Python 中的以下对象是可变的,这意味着它们在创建后可以被更改。

  1. 列表
  2. 字典
  3. 集合 (Sets)
  4. 其他可更改的对象,例如用户定义类的实例,这些实例具有可变属性。
  5. 具有返回 `None` 或引发异常的 `__hash__()` 方法的自定义对象。
  6. 函数,包括方法和 lambda 表达式。
  7. 文件对象。
  8. 网络套接字和其他 I/O 对象。

示例 1

让我们看一个例子。

程序

输出

The hash value for string -8608911714887531465
The hash value for tuple 590899387183067792
The hash value for float 922337203685490786

说明

内置的哈希函数接受输入并执行一些算法,然后返回哈希值。

示例 2

让我们考虑一个不为某些对象生成哈希值的程序。

程序

输出

ERROR!
Traceback (most recent call last):
	File "<string>", line 4, in <module>
TypeError: unhashable type: 'list'

说明

`hash()` 函数不能哈希可变对象,如列表、字典和集合。

示例 3

输出

1844674407370948697

说明

该代码的目的是定义一个名为 `MyHashableClass` 的自定义类,并使用值 89 创建该类的实例。然后,它使用 `hash()` 函数计算并打印该实例的哈希值。

Hashlib 库

Python 提供了多种哈希算法,可供用户根据自己的需求使用。Python 提供的内置哈希函数包括来自“hashlib”模块的加密函数,可用于哈希数据。让我们快速了解一些常用的哈希算法并学习如何使用它们。

SHA-1(安全哈希算法 1)

SHA-1 生成 160 位哈希值,过去曾被广泛使用。然而,由于存在漏洞,它现在在加密用途中被认为已弃用。

示例程序

输出

1477e90a7106add0a379f738f823e4c810cfceec

说明

SHA-1 接受输入并以十六进制格式生成 160 位输出。

SHA-256(安全哈希算法 256)

SHA-256 是 SHA-2 系列的一部分,并生成 256 位哈希值。它适用于大多数加密应用。

最常用的哈希算法是 SHA256 算法,它比 MD5 更安全。

示例程序

输出

0d5bad3f01155a5ec3e352d2925eee7700af0225f7891beccd1dc1ddef50393f

说明

SHA256 函数接受输入“SHA 256”并以 256 位长度的十六进制格式生成输出。

SHA-3(安全哈希算法 3)

SHA-3 是一系列安全哈希算法,可提供强大的安全性和高吞吐量。它有多种位长可供选择,例如 SHA-3-256,可生成 256 位哈希。

示例程序

输出

367f56e5e185665949cf91a86f88058ba5e724a0ddc7f91ef85a50b893ff828c

说明

SHA3 函数接受输入“SHA 3”并以十六进制格式生成 256 位长度的输出。

消息摘要(MD5())

MD5 函数生成 128 位哈希值,常用于校验和。然而,由于其漏洞,不建议用于加密目的。

示例程序

输出

9b10c9985311d8a19afc271140d7258e

说明

MD5() 函数接受输入“message digest”并生成 128 位哈希值。

SHA-384

安全哈希算法 2(SHA-2)系列包括称为 SHA-384 的函数,旨在确保加密安全。它生成 384 位(48 字节)的哈希值,是数据完整性验证、密码存储和其他加密应用的可靠哈希函数。

示例程序

输出

7bc670b88b26aabf94f6102c66ff3a28e6580174addb091675a3e034ea06968abe428c477a674a832d0ae44177398d76

说明

SHA-384 函数接受输入“ SHA384 Hashing ”并生成 384 位(48 字节)哈希。

SHA-224

SHA-224 函数属于 SHA-2 哈希函数系列,并生成 224 位(28 字节)哈希值。对于数据完整性检查,SHA-224 是一个可靠且安全的哈希函数,可用于加密目的。此哈希函数非常适合只需要较短哈希长度的情况。它通常代替 256 位或 512 位哈希,因为后者可能被认为过大。

要计算字符串的 SHA-224 哈希值,请看以下示例。

示例程序

输出

8552d8b7a7dc5476cb9e25dee69a8091290764b7f2a64fe6e78e9568

说明

Sha224 函数接受输入“Hello, world!”并生成 224 位输出。

SHA-512

SHA-512,或称安全哈希算法 512(SHA-512),是一种将任意长度文本转换为固定大小字符串的哈希算法。每个输出的长度为 512 位(64 字节)。它是一种安全且广泛使用的哈希函数,适用于各种加密和安全应用。

示例程序

输出

9592e8c12960603d57a43f5367177c44f0f8c08e4040a9cf380cf6cdef35b4cfbfa01eed16fea0c18206994afeb29d1091e658a310d16cd906d94d84a88a036b

说明

Sha512 函数接受输入“GOOD”并生成 512 位输出。

Blake2

Blake2 是一种快速且安全的加密哈希函数,可以生成不同长度的哈希输出。Blake2 的两个主要变体 Blake2b 和 Blake2s 具有不同的输出长度。

Blake2b:此变体允许生成各种长度的哈希输出,例如 256 位(32 字节)、384 位(48 字节)和 512 位(64 字节)。在创建 Blake2b 哈希对象时,可以指定所需的输出长度。

示例程序

输出

Blake2b 256-bit Hash: 4fa69a156f24d1f62e01757dcd998048ae036aed66cf72f002ca28143cddfc8f
Blake2b 384-bit Hash: 537747f30e72fe46f91ded3e6a33953ecbc708408ca839ebfd1a2074b3a03cb13abf399d87ca0e95a6a67c52cab4969e
Blake2b 512-bit Hash: 7c8f1ef9d911109531ddd5a990178c6568efe091c3f97648ece2c0ca0a526652074c7f3e13f23ea098786423485da832f4e60f912bfc179e8782a997df27e78c

说明

在此程序中,我们创建了三个 Blake2b 哈希对象实例,每个实例具有不同的输出长度:256 位、384 位和 512 位。然后,我们使用 UTF-8 编码的输入字符串“Hello, Blake2b!”更新每个哈希对象。之后,我们获取所有对象的哈希值的十六进制表示。最后,我们打印与每个输出长度关联的哈希值。

Blake2s:此变体专门用于生成较短的哈希长度。此哈希变体的输出长度通常为 128 位(16 字节)或 256 位(32 字节)。在创建 Blake2s 哈希对象时,可以指定所需的输出长度。

让我们看一个生成不同长度输出的简单程序。

示例程序

输出

Blake2s 128-bit Hash: d19972b915240fb371cf10c264473eaf
Blake2s 256-bit Hash: 98fe241a6c678f49d0513a0cc7c0f18ab8dff75ef0733d70440c7ca5d9a992eb

说明

在此程序中,我们使用 `hashlib.blake2s` 函数生成两个具有不同输出长度(即 128 位(16 字节)和 256 位(32 字节))的 Blake2s 哈希对象。然后,我们使用相同的输入字符串“Hello, Blake2s!”(UTF-8 编码)更新这两个哈希对象。最后,我们获取 128 位和 256 位版本的哈希值的十六进制表示,并打印它们。

RIPEMD

RIPEMD,即 RACE Integrity Primitives Evaluation Message Digest,是一组用于各种安全和加密应用的加密哈希函数。RIPEMD 最广为人知的版本是 RIPEMD-160 和 RIPEMD-128。为了让您更好地了解 RIPEMD 的作用及其用法,这里有一个概述。

RIPEMD-160:RIPEMD-160 生成 160 位哈希值。它用于数据完整性和加密货币,例如比特币。

示例程序

输出

RIPEMD-160 Hash: 2704a6e10487112bb98f615643b3c689c331f39c

说明

在此示例中,我们首先导入 `hashlib` 库。然后,我们通过使用 `hashlib.new('ripemd160')` 创建 RIPEMD-160 哈希对象。接下来,我们使用要哈希的数据更新哈希对象。最后,我们使用 `hexdigest()` 方法检索哈希值的十六进制表示。

RIPEMD-128:RIPEMD-128 生成 128 位哈希值,但其使用频率较低,与 RIPEMD-160 相比,在加密应用中的支持可能不那么广泛。

示例程序

输出

e999f30fc21ab12ab9ed89f55ba6a1de

说明

该程序以导入 `hashlib` 库开始。之后,我们使用 `hashlib.new('ripemd128')` 创建 RIPEMD-128 的哈希对象。然后,我们将要哈希的数据添加到哈希对象中。最后,我们使用 `hexdigest()` 方法获取哈希值的十六进制表示。

Bcrypt 哈希算法

Bcrypt 是最广泛使用的安全密码哈希算法,用于保护用户密码。密码被哈希后,无法还原为其原始形式。它是保护用户身份验证系统的关键组成部分。

bcrypt 的输出包括

  1. 一个指示哈希算法的前缀(例如,“$2a$”、“$2b$”、“$2y$”等)。
  2. 成本因子和盐。
  3. 实际的哈希密码。

示例程序

输出

$2b$12$g47LIm7P7q9NthP62I0MUOae6OWTS19ys1EL9NeNzF8le/eK3TRei

说明

上述程序接受输入并产生 60 个字符的输出。每次运行程序时,它都会产生不同的输出。

bcrypt 的输出包括

  1. 一个指示哈希算法的前缀(此处为“$2a$”)。
  2. 成本因子和盐。(上图中的 $12 是成本因子和盐)。
  3. 实际的哈希密码。(其余字符为哈希密码)。

优点

哈希是安全存储密码的重要过程。它允许高效的数据检索并确保数据完整性。哈希对于各种安全协议至关重要,例如消息认证码(MAC)、数字签名和数据完整性验证。此外,哈希算法对给定的输入产生一致且确定的输出,使其在数据安全方面非常可靠。

结论

哈希函数是计算机科学和安全领域的重要工具。它们对于确保数据完整性、效率和加密安全至关重要。哈希函数接受输入数据并创建一个唯一的固定大小的哈希值来表示输入。这使得检测原始数据中的任何微小变化都变得容易。哈希函数主要用于各种应用,如数据验证、密码存储、数字签名和像比特币这样的加密货币。像 SHA-256 和 SHA-3 这样的强大加密哈希函数通过提供原像抵抗和碰撞抵抗等属性,在确保数字系统安全方面发挥着关键作用。哈希函数的选择取决于应用程序的具体需求。采取谨慎措施对于适应不断变化的安全威胁和计算技术的进步至关重要。