Python Day17 常用模块 和 加解密操作 及例题分析
一、随机模块(random
)
random
模块提供多种生成随机数和操作随机序列的函数,常用于模拟、抽样、验证码生成等场景。
1. 核心函数
函数 | 功能描述 |
---|---|
random() | 返回[0, 1) 区间的随机小数 |
randrange(m, n) | 返回[m, n) 区间的随机整数(n 可省略,默认步长为 1) |
randint(m, n) | 返回[m, n] 区间的随机整数(包含两端) |
choice(seq) | 从序列seq 中随机返回 1 个元素 |
choices(seq, k=1) | 从序列seq 中随机返回k 个元素(允许重复,返回列表) |
sample(seq, k) | 从序列seq 中随机返回k 个元素(不重复,k ≤序列长度,返回列表) |
shuffle(list) | 随机打乱列表元素(原地修改,无返回值) |
2. 示例代码
import random# 随机小数
print(random.random()) # 例如:0.7625546555381723# 随机整数
print(random.randrange(1, 5)) # 1-4的随机整数(不含5)
print(random.randint(1, 5)) # 1-5的随机整数(含5)# 序列随机选择
print(random.choice('12345')) # 从字符串中选1个字符
print(random.choices([1,2,3], k=2)) # 允许重复:例如 [3, 1]
print(random.sample([1,2,3], k=2)) # 不重复:例如 [2, 1]# 列表打乱
ls = [1,2,3,4]
random.shuffle(ls)
print(ls) # 例如:[3, 1, 4, 2]
二、字符串模块(string
)
string
模块定义了多种常用字符串常量,简化字符串处理(如生成验证码、格式化等)。
1. 常用常量
常量 | 描述 | |
---|---|---|
ascii_lowercase | 小写字母:'abcdefghijklmnopqrstuvwxyz' | |
ascii_uppercase | 大写字母:'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | |
ascii_letters | 大小写字母组合(ascii_lowercase + ascii_uppercase ) | |
digits | 数字:'0123456789' | |
punctuation | 标点符号:'!"#$%&\'()*+,-./:;<=>?@[\\]^_ { | }~'` |
whitespace | 空白符:' \t\n\r\v\f' (空格、制表符、换行等) |
2. 应用示例:生成随机验证码
需求:6 位长度,由字母(大小写)和数字组成。
import string
import randomdef generate_code():# 组合所有可能的字符(字母+数字)all_chars = string.ascii_letters + string.digits# 从组合中随机选择6个不重复字符,拼接为字符串return ''.join(random.sample(all_chars, 6))print(generate_code()) # 例如:'K3f7Lp'
三、数学模块(math
)
math
模块提供基础数学运算函数,支持数值计算、三角函数、代数运算等。
1. 核心函数与常量
分类 | 函数 / 常量 | 描述 |
---|---|---|
取整 | floor(x) | 向下取整(如floor(3.8) → 3 ,floor(-3.2) → -4 ) |
ceil(x) | 向上取整(如ceil(3.2) → 4 ,ceil(-3.8) → -3 ) | |
公约数 / 阶乘 | gcd(*nums) | 求多个数的最大公约数(如gcd(18, 27) → 9 ) |
factorial(n) | 求n 的阶乘(如factorial(5) → 120 ) | |
数值判断 | isinf(n) | 判断n 是否为无穷大(如isinf(float('inf')) → True ) |
isfinite(n) | 判断n 是否为有限数(如isfinite(3.14) → True ) | |
isnan(n) | 判断n 是否为非数(如isnan(float('nan')) → True ) | |
幂 / 根 | sqrt(n) | 求n 的算术平方根(如sqrt(16) → 4.0 ) |
isqrt(n) | 求n 的算术平方根的整数部分(如isqrt(17) → 4 ) | |
pow(x, y) | 求x 的y 次幂(等价于x**y ) | |
三角函数 | sin(rad) | 正弦值(参数为弧度,如sin(pi/2) → 1.0 ) |
cos(rad) | 余弦值(如cos(pi) → -1.0 ) | |
tan(rad) | 正切值(如tan(pi/4) → 1.0 ) | |
常量 | pi | 圆周率(约 3.141592653589793) |
2. 角度与弧度转换
- 角度转弧度:
弧度 = 角度 × π / 180
- 弧度转角度:
角度 = 弧度 × 180 / π
3. 应用示例:计算时钟刻度坐标
import mathdef get_clock_locations(radius, center=(0, 0)):"""计算时钟12个刻度的坐标(以圆心为center,半径为radius)"""locations = []for hour in range(12):# 每个刻度与12点的夹角(30度/小时:360°÷12=30°)degrees = hour * 30# 角度转弧度radians = degrees * math.pi / 180# 计算坐标(基于圆心偏移)x = center[0] + radius * math.sin(radians)y = center[1] + radius - radius * math.cos(radians) # y轴向下为正locations.append((round(x, 2), round(y, 2)))return locationsprint(get_clock_locations(10))
# 输出示例:[(0.0, 20.0), (5.0, 18.66), (8.66, 15.0), ...]
四、加密模块(哈希、RSA 等)
加密技术用于数据安全传输和存储,常见分类包括不可逆加密、对称加密、非对称加密。
1. 不可逆加密(哈希算法)
- 特点:只能加密,无法解密,相同输入必产生相同输出。
- 常用算法:
md5
、sha-1
、sha-256
(通过hashlib
模块实现)。
示例:md5
与sha-1
加密
import hashlibpassword = "我爱你"
# 加密需先将字符串转为字节(utf-8编码)
md5_hash = hashlib.md5(password.encode()).hexdigest()
sha1_hash = hashlib.sha1(password.encode()).hexdigest()print("MD5加密结果:", md5_hash) # 32位字符串
print("SHA-1加密结果:", sha1_hash) # 40位字符串
2. 非对称加密(RSA)
- 特点:使用公钥加密、私钥解密,需安装第三方库
rsa
(pip install rsa
)。 - 应用:安全传输敏感信息(如密码、令牌)。
步骤 1:生成密钥对并保存
import rsa# 生成2048位密钥对(公钥+私钥)
public_key, private_key = rsa.newkeys(2048)# 保存公钥到文件(用于加密)
with open("public.pem", "wb") as f:f.write(public_key.save_pkcs1())# 保存私钥到文件(用于解密)
with open("private.pem", "wb") as f:f.write(private_key.save_pkcs1())
步骤 2:公钥加密
import rsa
import base64
from urllib.parse import quotemessage = "你好,老刘"# 加载公钥
with open("public.pem", "rb") as f:public_key = rsa.PublicKey.load_pkcs1(f.read())# 加密(结果为字节)
encrypted_bytes = rsa.encrypt(message.encode(), public_key)
# Base64编码为字符串(便于传输)
encrypted_text = base64.b64encode(encrypted_bytes).decode()
# URL转义(处理特殊字符如+、/、=)
encrypted_url = quote(encrypted_text)print("加密后(URL安全):", encrypted_url)
步骤 3:私钥解密
import rsa
import base64
from urllib.parse import unquote# 加载私钥
with open("private.pem", "rb") as f:private_key = rsa.PrivateKey.load_pkcs1(f.read())# 解密步骤:URL解码 → Base64解码 → 私钥解密
encrypted_text = unquote(encrypted_url)
encrypted_bytes = base64.b64decode(encrypted_text.encode())
decrypted_message = rsa.decrypt(encrypted_bytes, private_key).decode()print("解密结果:", decrypted_message) # 输出:你好,老刘
3. 数字签名(防篡改)
- 原理:用私钥签名数据,用公钥验证,确保数据未被篡改。
示例:私钥签名与公钥验证
import rsa
import base64
from urllib.parse import quote, unquotemessage = "I love you!"# 私钥签名
with open("private.pem", "rb") as f:private_key = rsa.PrivateKey.load_pkcs1(f.read())
signature_bytes = rsa.sign(message.encode(), private_key, "SHA-1")
signature_text = quote(base64.b64encode(signature_bytes).decode())# 公钥验证
with open("public.pem", "rb") as f:public_key = rsa.PublicKey.load_pkcs1(f.read())
signature_bytes = base64.b64decode(unquote(signature_text).encode())
try:# 验证成功返回哈希算法,失败抛出异常hash_method = rsa.verify(message.encode(), signature_bytes, public_key)print("验证成功,哈希算法:", hash_method) # 输出:SHA-1
except rsa.VerificationError:print("验证失败,数据被篡改!")
五、第三方库安装
- 安装:
pip install <库名>
(如pip install rsa
)。 - 国内镜像:加速安装(如阿里云、豆瓣源),临时使用:
pip install <库名> -i https://pypi.douban.com/simple/
- 导出依赖:
pip freeze > requirements.txt
(生成项目依赖列表)。 - 安装依赖:
pip install -r requirements.txt
(批量安装依赖)。
以上整理覆盖了random
、string
、math
模块的核心功能及加密技术的实践应用,通过示例代码强化对知识点的理解和使用。
一、随机模块应用
1. 生成 UUID
UUID 格式为xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(8-4-4-4-12 结构),由0-9
和a-f
组成。
import randomdef generator_uuid():# 定义UUID允许的字符集chars = "0123456789abcdef"# 按格式生成各段并拼接return f"{''.join(random.choices(chars, k=8))}-" \f"{''.join(random.choices(chars, k=4))}-" \f"{''.join(random.choices(chars, k=4))}-" \f"{''.join(random.choices(chars, k=4))}-" \f"{''.join(random.choices(chars, k=12))}"# 测试
print(generator_uuid()) # 示例:f47ac10b-58cc-4372-a567-0e02b2c3d479
2. 生成唯一订单编号
订单编号格式:yyyyMMddHHmmss + 随机数字
(随机数字长度默认为 5)。
import random
import timedef generator_ordernum(num=5):# 获取当前时间(年月日时分秒)timestamp = time.strftime("%Y%m%d%H%M%S", time.localtime())# 生成指定长度的随机数字(1-9,避免首位为0)random_suffix = ''.join(random.choices('123456789', k=num))return timestamp + random_suffix# 测试
print(generator_ordernum(num=5)) # 示例:2024072915304578923
二、数学模块应用:计算钟表刻度坐标
根据钟表外切正方形左上角坐标(center
)和半径(radius
),返回 12 个整点的坐标字典。
import mathdef get_clock_location(center=(0, 0), radius=100):location_dict = {}for hour in range(12):# 计算角度(每小时30度:360°÷12)degrees = hour * 30# 角度转弧度radians = degrees * math.pi / 180# 计算相对圆心的坐标(以钟表中心为原点)# 正弦对应x轴偏移,余弦对应y轴偏移(y轴向下为正)x = radius + math.sin(radians) * radiusy = radius - math.cos(radians) * radius# 加上外切正方形左上角坐标偏移actual_x = round(center[0] + x, 1)actual_y = round(center[1] + y, 1)location_dict[hour] = (actual_x, actual_y)return location_dict# 测试
print(get_clock_location(center=(0, 0), radius=100))
# 示例输出:{0: (100.0, 0.0), 1: (150.0, 13.4), ...}
三、随机日期生成与验证
生成 1900-2100 年的随机日期,验证合法性并计算星期和当年天数。
1. 核心函数
import randomdef generate_random_date():"""生成随机日期(年-月-日字符串)"""year = random.choice(range(1900, 2101))month = random.choice(range(1, 13))day = random.choice(range(1, 32))return f"{year}-{month}-{day}"def is_valid_date(date_str):"""验证日期合法性"""year, month, day = map(int, date_str.split('-'))# 大月(1,3,5,7,8,10,12)最多31天if month in [1,3,5,7,8,10,12] and day > 31:return False# 小月(4,6,9,11)最多30天if month in [4,6,9,11] and day > 30:return False# 2月:闰年29天,平年28天if month == 2:is_leap = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)if day > 29 or (not is_leap and day > 28):return Falsereturn Truedef get_weekday(date_str):"""计算日期对应的星期(0=周一,6=周日)"""if not is_valid_date(date_str):return Noneyear, month, day = map(int, date_str.split('-'))# 调整月份和年份(Zeller公式适配)if month < 3:month += 12year -= 1c = year // 100 # 世纪y = year % 100 # 年份后两位# Zeller公式计算星期(0=周六,6=周五)w = (day + (13 * (month + 1)) // 5 + y + y//4 + c//4 - 2*c) % 7# 转换为0=周一,6=周日return (w + 5) % 7def get_day_of_year(date_str):"""计算日期是当年的第几天"""if not is_valid_date(date_str):return Noneyear, month, day = map(int, date_str.split('-'))# 每月天数(闰年2月29天)days_in_month = [31,28,31,30,31,30,31,31,30,31,30,31]if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):days_in_month[1] = 29 # 闰年调整# 累加前几个月的天数return sum(days_in_month[:month-1]) + day
2. 测试代码
if __name__ == '__main__':date = generate_random_date()print(f"随机日期: {date}")if is_valid_date(date):print(f"日期合法")weekday_map = {0: "周一", 1: "周二", 2: "周三", 3: "周四", 4: "周五", 5: "周六", 6: "周日"}print(f"星期: {weekday_map[get_weekday(date)]}")print(f"当年第{get_day_of_year(date)}天")else:print("日期不合法")
四、加密工具类(Security
)
封装 MD5、SHA256 加密及 RSA 签名 / 验证、加解密功能。
import hashlib
import rsa
import base64
from urllib.parse import quote, unquoteclass Security:@classmethoddef md5(cls, text: str) -> str:"""MD5加密"""return hashlib.md5(text.encode()).hexdigest()@classmethoddef sha256(cls, text: str) -> str:"""SHA256加密"""return hashlib.sha256(text.encode()).hexdigest()@classmethoddef sign(cls, message: str, private_key, hash_method='MD5') -> str:"""私钥签名(返回Base64编码)"""signature = rsa.sign(message.encode(), private_key, hash_method)return base64.b64encode(signature).decode()@classmethoddef sign2(cls, message: str, private_key, hash_method='MD5') -> str:"""私钥签名(返回URL编码)"""return quote(cls.sign(message, private_key, hash_method))@classmethoddef verify(cls, message: str, signature: str, public_key, hash_method=None) -> bool:"""公钥验证签名"""try:signature_bytes = base64.b64decode(unquote(signature).encode())rsa.verify(message.encode(), signature_bytes, public_key)return Trueexcept rsa.VerificationError:return False@classmethoddef encrypt(cls, message: str, public_key) -> str:"""公钥加密(返回Base64编码)"""encrypted = rsa.encrypt(message.encode(), public_key)return base64.b64encode(encrypted).decode()@classmethoddef decrypt(cls, secure_text: str, private_key) -> str:"""私钥解密"""encrypted_bytes = base64.b64decode(secure_text)return rsa.decrypt(encrypted_bytes, private_key).decode()
五、URL 签名与验证
对 URL 参数进行签名并验证,确保参数未被篡改。
1. URL 签名(添加sign
参数)
def add_sign(url: str, private_key, hash_method="MD5") -> str:"""对URL参数签名并拼接sign参数"""# 分离基础URL和参数base_url, params = url.split('?')# 生成签名signature = Security.sign(params, private_key, hash_method)# URL编码签名并拼接return f"{url}&sign={quote(signature)}"
2. URL 验证(验证sign
参数)
def verify_url(url: str, public_key, hash_method="MD5") -> bool:"""验证URL参数签名合法性"""# 分离参数和签名params_part, signature = url.split('&sign=')# 提取原始参数(不含sign)params = params_part.split('?')[1]# 验证签名return Security.verify(params, signature, public_key, hash_method)
3. 测试代码
if __name__ == '__main__':# 生成RSA密钥对public_key, private_key = rsa.newkeys(2048)# 原始URLurl = "https://www.test.com/abc?a=1&b=2&c=3"print(f"原始URL: {url}")# 签名URLsigned_url = add_sign(url, private_key)print(f"签名后URL: {signed_url}")# 验证签名is_valid = verify_url(signed_url, public_key)print(f"签名验证结果: {'合法' if is_valid else '非法'}")
以上整理覆盖了随机模块、数学模块的实际应用,以及加密技术在 URL 安全中的实践,通过函数封装和示例代码强化了可复用性和理解。