短信邮件
eval
简介
eval()
是 Python 的一个内置函数,用于执行一个字符串表达式,并返回表达式的值。
基本语法
1 | eval(expression, globals=None, locals=None) |
- expression: 字符串形式的 Python 表达式
- globals (可选): 字典形式的全局命名空间
- locals (可选): 字典形式的局部命名空间
基本用法
1 | x = 1 |
主要特点
-
执行字符串表达式:
1
print(eval('2 + 3 * 4')) # 输出: 14
-
可以访问变量:
1
2a = 5
print(eval('a * 2')) # 输出: 10 -
可以调用函数:
1
2
3
4def square(n):
return n * n
print(eval('square(5)')) # 输出: 25
安全性问题
eval()
可以执行任意 Python 代码,因此存在安全风险:
1 | # 危险示例 - 不要在实际应用中使用这样的代码 |
限制执行环境
为了安全,可以限制 eval()
的执行环境:
1 | from math import * |
与 exec() 的区别
eval()
只能计算单个表达式并返回值exec()
可以执行更复杂的代码块,但不返回值
替代方案
对于简单的表达式计算,可以考虑更安全的替代方案:
-
使用
ast.literal_eval()
(只能计算字面量表达式):1
2import ast
print(ast.literal_eval("[1, 2, 3]")) # 输出: [1, 2, 3] -
使用特定领域的解析器 (如数学表达式解析器)
简介
hashlib
是 Python 标准库中的一个模块,提供了多种安全哈希算法和消息摘要算法的实现。这些算法可用于数据完整性验证、密码存储、数字签名等安全相关场景。
主要特性
- 提供了多种哈希算法:MD5、SHA1、SHA224、SHA256、SHA384、SHA512 等
- 支持更安全的算法如 SHA3 和 BLAKE2(取决于 Python 版本)
- 使用简单统一的接口
- 支持增量哈希计算
常用哈希算法
1 | import hashlib |
基本使用方法
-
简单哈希计算
1
2
3
4
5
6
7import hashlib
# 计算字符串的SHA256哈希值
data = "Hello, world!"
hash_object = hashlib.sha256(data.encode())
hex_digest = hash_object.hexdigest()
print(hex_digest) # 输出16进制表示的哈希值 -
增量更新哈希
1
2
3
4hash_object = hashlib.sha256()
hash_object.update(b"Hello, ")
hash_object.update(b"world!")
print(hash_object.hexdigest()) -
使用不同的输出格式
1
2
3
4
5
6
7
8
9
10
11
12
13hash_object = hashlib.sha256(b"Hello, world!")
# 16进制字符串
print(hash_object.hexdigest())
# 二进制digest
print(hash_object.digest())
# 摘要长度(字节数)
print(hash_object.digest_size)
# 算法名称
print(hash_object.name)
安全注意事项
- 不要使用 MD5 和 SHA1 用于密码存储或安全敏感用途,它们已被证明不安全
- 对于密码存储,应使用专门的密码哈希函数如 PBKDF2, bcrypt 或 scrypt
- Python 的
hashlib
也提供了hashlib.pbkdf2_hmac()
用于密码哈希
密码哈希示例
1 | import hashlib |
新算法支持
在较新的 Python 版本中(3.6+),hashlib
还支持:
- SHA3 算法系列
- BLAKE2 算法系列
hashlib.scrypt()
函数(Python 3.6+)
urllib
- 说明:
- URI:统一资源标识符
- URL:统一资源定位符,URI的一种形式,如:
http://www.baidu.com:80?name=xiaoming&age=10
- 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26from urllib.parse import urlencode
d = {'name': 'dahua', 'age': 10}
print(d)
# 转换为:name=dahua&age=10
print(urlencode(d))
from urllib.parse import urlparse
url = 'http://www.baidu.com:80/abc/def?page=3&size=5'
# 解析出url中所有的参数
# 结果:ParseResult(scheme='http', netloc='www.baidu.com:80', path='/abc/def', params='', query='page=3&size=5', fragment='')
p = urlparse(url)
print(p)
# 请求参数
print(p.query)
from urllib.parse import parse_qs
# 将url请求参数转换成字典
# 结果:{'page': ['3'], 'size': ['5']}
d = parse_qs(p.query)
print(d)
http.client
- 说明: 可以模拟浏览器发送http请求(是爬虫的基础)
- 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13import http.client
# 创建连接(相当于浏览器)
connect = http.client.HTTPConnection('www.baidu.com')
# 发送请求(GET、POST)
connect.request(method='GET', url='https://www.baidu.com/')
# 获取响应
resp = connect.getresponse()
# 打印响应内容,读取并解码
print(resp.read().decode('utf-8'))
邮件发送
- 说明: 在一个网站中经常使用邮件操作,如:激活、通知、等
- smtp使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39import os
import smtplib
# 将字符串转换为邮件的文本格式
from email.mime.text import MIMEText
# 邮箱服务器
mail_server = 'smtp.163.com'
# 用户名
mail_user = '16666666@163.com'
# 密码或授权码,为了不将密码公开,可以通过环境变量的形式获取
mail_password = os.environ.get('MAIL_PASSWORD') or '123456'
# mail_password = 'suyin'
# 邮件消息
message = '你好,欢迎注册xxx平台,激活请点击右边链接<a href="https://www.baidu.com/">百度一下</a>'
# 将邮件字符串消息转换成邮件格式,若内容是HTML需要指定第二个参数为'html'
message = MIMEText(message, 'html')
# 设置主题
message['Subject'] = '账户激活'
# 设置发送人
message['From'] = mail_user
# 创建邮件对象
mail = smtplib.SMTP(mail_server, 25)
# 登录服务器
mail.login(mail_user, mail_password)
# 接收者,多个使用逗号隔开
to = '155555555555@163.com'
# 发送邮件
mail.sendmail(mail_user, to, message.as_string())
# 结束
mail.quit()
短信发送
- 说明: 注册验证码、通知消息、营销短息、…
- 短信发送平台: 阿里、云之讯、秒滴、…
- 示例: 秒滴(http://www.miaodiyun.com)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56import time
import hashlib
import http.client
from urllib.parse import urlencode
# 请求地址
url = 'https://api.miaodiyun.com/20150822/industrySMS/sendSMS'
# 请求头
headers = {'Content-type': 'application/x-www-form-urlencoded'}
# 账户id
accountSid = '8d7ec5467c27456b859d727268b62ca9'
# auth token
auth_token = '62438af2632f448c94b028a1641b3906'
# 时间戳
timestamp = time.strftime('%Y%m%d%H%M%S')
sig = accountSid + auth_token + timestamp
# 加密一下
md = hashlib.md5()
md.update(sig.encode('utf-8'))
sig = md.hexdigest()
# 模板参数
yzm = '632881'
t = '5'
param = yzm + ',' + t
# 表单数据
form_data = {
'accountSid': accountSid,
'templateid': '1502437573',
'to': '16657158725',
'timestamp': timestamp,
'sig': sig,
'param': param
}
# 将字典转换为url参数形式
form_data = urlencode(form_data)
# 创建浏览器对象
connect = http.client.HTTPConnection('api.miaodiyun.com')
# 发送POST请求
connect.request(method='POST', url=url, body=form_data, headers=headers)
# 获取响应;
resp = connect.getresponse()
# 打印响应结果
print(resp.read().decode('utf-8'))