Skip to main content

Python 常用内置模块

Python 内置模块 hashlib

hashlib 是 Python 的内置模块,提供了各种哈希算法的接口,包括 MD5、SHA1、SHA256 等。哈希函数将任意长度的数据转换为固定长度的字符串,广泛应用于数据完整性验证、密码存储、数字签名等场景。

哈希函数具有以下特点:

  • 确定性:相同输入总是产生相同输出
  • 不可逆:无法从哈希值推导出原始数据
  • 雪崩效应:输入微小变化导致输出巨大变化
  • 固定长度:无论输入多长,输出长度固定

导入模块

import hashlib

# 查看支持的哈希算法
print("可用算法:", hashlib.algorithms_available)
print("保证可用算法:", hashlib.algorithms_guaranteed)

基本使用方法

MD5 哈希

import hashlib

# 创建 MD5 哈希对象
md5_hash = hashlib.md5()

# 更新数据(必须是字节类型)
data = "Hello, World!"
md5_hash.update(data.encode('utf-8'))

# 获取十六进制哈希值
hex_digest = md5_hash.hexdigest()
print(f"MD5 哈希值: {hex_digest}")

# 获取二进制哈希值
binary_digest = md5_hash.digest()
print(f"二进制哈希值长度: {len(binary_digest)} 字节")

SHA256 哈希

import hashlib

# 直接计算 SHA256
text = "Python hashlib 教程"
sha256_hash = hashlib.sha256(text.encode('utf-8'))
result = sha256_hash.hexdigest()
print(f"SHA256 哈希值: {result}")

常用哈希算法

SHA 系列算法

import hashlib

data = "测试数据".encode('utf-8')

# SHA1
sha1 = hashlib.sha1(data).hexdigest()
print(f"SHA1:   {sha1}")

# SHA224
sha224 = hashlib.sha224(data).hexdigest()
print(f"SHA224: {sha224}")

# SHA256
sha256 = hashlib.sha256(data).hexdigest()
print(f"SHA256: {sha256}")

# SHA384
sha384 = hashlib.sha384(data).hexdigest()
print(f"SHA384: {sha384}")

# SHA512
sha512 = hashlib.sha512(data).hexdigest()
print(f"SHA512: {sha512}")

通用哈希函数

import hashlib

def calculate_hash(data, algorithm='sha256'):
    """通用哈希计算函数"""
    if isinstance(data, str):
        data = data.encode('utf-8')
    
    hash_obj = hashlib.new(algorithm)
    hash_obj.update(data)
    return hash_obj.hexdigest()

# 使用示例
text = "通用哈希函数测试"
print(f"MD5:    {calculate_hash(text, 'md5')}")
print(f"SHA1:   {calculate_hash(text, 'sha1')}")
print(f"SHA256: {calculate_hash(text, 'sha256')}")

处理大文件

逐块读取文件

import hashlib

def file_hash(filename, algorithm='sha256', chunk_size=8192):
    """计算文件哈希值"""
    hash_obj = hashlib.new(algorithm)
    
    try:
        with open(filename, 'rb') as f:
            # 逐块读取文件,避免内存溢出
            while chunk := f.read(chunk_size):
                hash_obj.update(chunk)
        return hash_obj.hexdigest()
    except FileNotFoundError:
        return None

# 使用示例(假设文件存在)
# result = file_hash('large_file.txt')
# if result:
#     print(f"文件哈希值: {result}")
# else:
#     print("文件不存在")

多次更新哈希对象

import hashlib

# 创建哈希对象
sha256_hash = hashlib.sha256()

# 分多次更新数据
data_chunks = ["第一部分数据", "第二部分数据", "第三部分数据"]

for chunk in data_chunks:
    sha256_hash.update(chunk.encode('utf-8'))

final_hash = sha256_hash.hexdigest()
print(f"分块更新的哈希值: {final_hash}")

# 对比一次性计算的结果
all_data = "".join(data_chunks)
one_time_hash = hashlib.sha256(all_data.encode('utf-8')).hexdigest()
print(f"一次性计算哈希值: {one_time_hash}")
print(f"结果相同: {final_hash == one_time_hash}")

密码哈希与安全

加盐哈希

import hashlib
import secrets

def hash_password(password):
    """生成加盐密码哈希"""
    # 生成随机盐值
    salt = secrets.token_hex(16)
    
    # 密码与盐值结合
    salted_password = password + salt
    
    # 计算哈希
    password_hash = hashlib.sha256(salted_password.encode('utf-8')).hexdigest()
    
    # 返回盐值和哈希值
    return salt, password_hash

def verify_password(password, salt, stored_hash):
    """验证密码"""
    salted_password = password + salt
    calculated_hash = hashlib.sha256(salted_password.encode('utf-8')).hexdigest()
    return calculated_hash == stored_hash

# 使用示例
password = "my_secure_password"
salt, hashed = hash_password(password)
print(f"盐值: {salt}")
print(f"哈希: {hashed}")

# 验证密码
is_valid = verify_password(password, salt, hashed)
is_invalid = verify_password("wrong_password", salt, hashed)
print(f"正确密码验证: {is_valid}")
print(f"错误密码验证: {is_invalid}")

数据完整性验证

文件完整性检查

import hashlib

def generate_checksum(data):
    """生成数据校验和"""
    return hashlib.md5(data.encode('utf-8')).hexdigest()

def verify_integrity(original_data, received_data):
    """验证数据完整性"""
    original_checksum = generate_checksum(original_data)
    received_checksum = generate_checksum(received_data)
    
    print(f"原始校验和: {original_checksum}")
    print(f"接收校验和: {received_checksum}")
    
    return original_checksum == received_checksum

# 模拟数据传输
original = "重要的数据内容"
received_correct = "重要的数据内容"
received_corrupted = "重要的数椐内容"  # 注意:数据被篡改

print("完整数据验证:")
print(f"验证结果: {verify_integrity(original, received_correct)}")

print("\n损坏数据验证:")
print(f"验证结果: {verify_integrity(original, received_corrupted)}")

性能对比

import hashlib
import time

def benchmark_algorithms(data, iterations=10000):
    """对比不同哈希算法的性能"""
    algorithms = ['md5', 'sha1', 'sha256', 'sha512']
    results = {}
    
    test_data = data.encode('utf-8')
    
    for algorithm in algorithms:
        start_time = time.time()
        
        for _ in range(iterations):
            hashlib.new(algorithm, test_data).hexdigest()
        
        end_time = time.time()
        results[algorithm] = end_time - start_time
    
    return results

# 性能测试
test_string = "性能测试数据" * 100
performance = benchmark_algorithms(test_string)

print("哈希算法性能对比(秒):")
for algo, time_taken in performance.items():
    print(f"{algo.upper()}: {time_taken:.4f}")

注意事项

  1. 编码问题:字符串必须编码为字节类型才能进行哈希计算
  2. 安全性考量:MD5 和 SHA1 已不推荐用于安全应用,建议使用 SHA256 或更高版本
  3. 密码存储:直接哈希密码不安全,应使用加盐哈希或专门的密码哈希函数
  4. 性能考虑:处理大文件时应分块读取,避免内存溢出