当前位置: 首页 > news >正文

一文详细讲解Python(详细版一篇学会Python基础和网络安全)

引言

在当今数字化时代,Python 作为一种简洁高效且功能强大的编程语言,广泛应用于各个领域,从数据科学、人工智能到网络安全等,都能看到 Python 的身影。而网络安全作为保障信息系统和数据安全的关键领域,其重要性不言而喻。

Python 凭借丰富的库和模块,为网络安全的各个方面提供了强大的支持。无论是对加密算法的实现、文件的安全操作,还是对网络流量的分析、渗透测试等,Python 都能发挥重要作用。深入学习 Python 编程与网络安全知识,不仅有助于我们理解计算机系统的运行机制,更能让我们具备保护信息安全的能力,抵御日益复杂的网络攻击。

接下来,我们将全面深入地探讨 Python 编程在网络安全领域的应用,从基础的文件操作、函数模块的使用,到高级的多进程多线程编程、面向对象程序设计,再到网络安全应用的综合实践,逐步揭示 Python 与网络安全的奥秘。

第 1 章 概述

1.1 Python 语言简介

  • 发展历史:Python 由吉多・范罗苏姆在 20 世纪 80 年代末开始开发,于 1991 年发布首个公开发行版。此后,Python 社区不断对其进行更新和完善,新的版本添加了更多的功能和优化,使其能更好地适应不同的应用场景。
  • 特点
    • 语法简洁易读:Python 采用简洁的语法结构,代码风格清晰,降低了编程的难度,新手也能快速上手。例如,实现一个简单的打印功能,只需一行代码print("Hello, World!")
    • 动态类型系统:在 Python 中,变量无需提前声明类型,在赋值时会自动确定类型。比如a = 10,这里a被确定为整数类型;若后续执行a = "hello"a又变成了字符串类型。
    • 开源免费:Python 是开源的,这意味着其源代码可以免费获取和使用,并且全球的开发者可以共同参与其开发和改进。
    • 丰富的库和框架:Python 拥有大量的第三方库和框架,涵盖了各个领域。例如,在 Web 开发领域有 Django、Flask;在数据科学领域有 NumPy、pandas;在人工智能领域有 TensorFlow、PyTorch 等。这些库和框架大大提高了开发效率。
  • 应用领域
    • Web 开发Django 和 Flask 是 Python 中常用的 Web 开发框架。Django 功能强大,提供了丰富的内置功能,如数据库管理、用户认证等,适合开发大型的 Web 应用;Flask 则是一个轻量级的框架,灵活性高,适合快速开发小型 Web 应用。
    • 数据科学:Python 在数据分析、可视化等方面表现出色。NumPy 提供了高效的多维数组对象和数学函数;pandas 用于数据处理和分析;Matplotlib 和 Seaborn 可用于数据可视化。
    • 人工智能:机器学习和深度学习是人工智能的重要分支。Python 中的 Scikit - learn 提供了丰富的机器学习算法和工具;TensorFlow 和 PyTorch 则是流行的深度学习框架,可用于构建和训练神经网络模型。
    • 自动化脚本:Python 可以编写各种自动化脚本,如文件处理、系统管理等脚本,提高工作效率。

1.2 Python 开发环境的安装和使用

  • IDLE:它是 Python 自带的轻量级集成开发环境,适合初学者。IDLE 具备基本的代码编辑、运行和调试功能,打开 IDLE 后可以直接编写和运行 Python 代码,还能进行简单的调试操作。
  • PyCharm:这是一款功能强大的专业 Python 集成开发环境。它支持代码智能提示,在编写代码时能自动补全代码,提高编码效率;具备强大的调试功能,可以设置断点、单步执行等;还支持版本控制,方便团队协作开发。
  • Anaconda:是一个用于科学计算的 Python 发行版。它集成了众多常用的科学计算库,如 NumPy、pandas、Matplotlib 等,还提供了包管理器 conda。通过 conda 可以方便地安装、更新和卸载各种库和工具,同时也能管理不同的 Python 环境。
  • Jupyter Notebook:是一个交互式笔记本环境。它可以将代码、文本说明、可视化结果等整合在一个文档中,方便代码演示、分享和协作。在 Jupyter Notebook 中,代码可以逐块运行,并且能实时看到运行结果。

1.3 支持库的管理

Python 通过包管理器来管理支持库,常见的包管理器有 pip 和 conda。

  • pip:是 Python 默认的包管理器。使用pip install 库名可以安装指定的库,例如pip install requests可以安装用于 HTTP 请求的requests库;pip list可以查看已安装的库列表。
  • conda:是 Anaconda 发行版中的包管理器,它不仅可以管理 Python 库,还可以管理其他语言的包和工具。使用conda install 库名可以安装库,conda list可以查看已安装的库列表。

1.4 如何学好编程

  • 打好基础知识:掌握 Python 的语法规则、数据类型、控制结构等基础知识是学好编程的关键。只有基础扎实,才能更好地理解和运用高级知识。
  • 多做练习题和小项目:通过做练习题可以加深对知识点的理解和掌握;参与小项目可以将所学知识应用到实际中,积累实践经验,提高解决问题的能力。
  • 阅读优秀的开源代码:开源社区中有很多优秀的 Python 代码,阅读这些代码可以学习他人的编程思路、设计模式和代码规范,提升自己的编程水平。
  • 积极参与技术社区交流:在技术社区中可以与其他开发者交流经验、分享心得,遇到问题时也能得到及时的帮助和解决方案。

第 2 章 基本数据类型

2.1 变量

  • 变量的定义:在 Python 中,通过赋值语句来定义变量,变量无需提前声明类型。例如a = 10,这里a就是一个变量,被赋值为整数 10。
  • 变量的命名规则
    • 由字母、数字和下划线组成。
    • 不能以数字开头,例如1var是不合法的变量名,而var1是合法的。
    • 不能使用 Python 关键字,如ifelsefor等。
    • 命名应具有描述性,例如student_namea更能清晰地表达变量的含义。
  • 查看关键字和内置函数
    • 可以通过keyword模块查看 Python 的关键字,示例代码如下:
import keyword
print(keyword.kwlist)
  • 通过dir(__builtins__)查看内置函数列表,示例代码如下:
print(dir(__builtins__))
  • 常量:Python 中没有严格意义上的常量,通常通过全大写字母命名的变量来表示常量,约定其值不被修改。例如PI = 3.14159

2.2 数字类型

  • 整数、浮点数和复数
    • 整数:表示没有小数部分的数,如10-5等。
    • 浮点数:用于表示带有小数部分的数,如3.14-2.5等。
    • 复数:由实部和虚部组成,使用j表示虚部,如3 + 4j
  • 进制之间的转换
    • 二进制以0b为前缀,八进制以0o为前缀,十六进制以0x为前缀。可以使用内置函数进行进制转换,例如:
# 十进制转二进制
print(bin(10))  # 输出 0b1010
# 十进制转八进制
print(oct(10))  # 输出 0o12
# 十进制转十六进制
print(hex(10))  # 输出 0xa
  • 内置模块
    • math 模块:提供了许多数学运算函数,如三角函数(sin()cos()等)、对数函数(log())等。示例代码如下:
import math
print(math.sin(math.pi / 2))  # 输出 1.0
  • cmath 模块:用于复数的数学运算,示例代码如下:
import cmath
z = 3 + 4j
print(cmath.sqrt(z))

2.3 字符串

  • 字符串的表示
    • 可以使用单引号(')、双引号(")或三引号('''""")来表示字符串。例如:
s1 = 'hello'
s2 = "world"
s3 = '''This is a
multi - line string.'''
  • 三引号可用于表示多行字符串。
  • 字符串的常用操作
    • 拼接:使用+号进行字符串拼接,例如:
s1 = "Hello"
s2 = " World"
print(s1 + s2)  # 输出 Hello World
  • 切片:通过索引获取子串,例如:
s = "Hello World"
print(s[1:3])  # 输出 el

 

  • 查找:使用find()方法查找子串首次出现的索引,例如:
s = "Hello World"
print(s.find("World"))  # 输出 6

 

  • 替换:使用replace()方法替换子串,例如:
s = "Hello World"
print(s.replace("World", "Python"))  # 输出 Hello Python

2.4 基本的输入和输出

  • 输入函数:使用input()函数获取用户从控制台输入的内容,返回值为字符串类型。示例代码如下:
name = input("请输入你的名字:")
print(f"你好,{name}")
  • 输出函数:使用print()函数将结果输出到控制台,可自定义输出格式,如设置分隔符和结束符。示例代码如下:
print("Hello", "World", sep=", ", end="!\n")  # 输出 Hello, World!

2.5 代码规范

遵循 PEP 8 编码规范可以提高代码的可读性和可维护性。例如:

  • 使用 4 个空格进行缩进,而不是制表符。
  • 合理命名变量和函数,变量名使用小写字母,函数名使用小写字母和下划线的组合。
  • 适当添加注释,解释代码的功能和逻辑。

2.6 字符编码

常见的字符编码有 ASCII、UTF - 8 等。

  • ASCII:是最早的字符编码标准,只能表示英文字母、数字和一些特殊字符,共 128 个字符。
  • UTF - 8:是一种可变长度的字符编码,它可以表示世界上几乎所有的字符,是目前互联网上使用最广泛的字符编码。在处理文本数据时,要了解不同编码的特点和适用场景,避免出现编码错误。

第 3 章 复合数据类型

3.1 序列数据

  • 序列简介:序列是一种有序的数据集合,元素按顺序排列,可以通过索引访问。常见的序列类型包括列表和元组。
  • 创建列表和元组
    • 列表:使用方括号[]创建,例如my_list = [1, 2, 3]
    • 元组:使用圆括号()创建,例如my_tuple = (1, 2, 3),也可省略括号,如my_tuple = 1, 2, 3

3.2 列表和元组通用方法

  • 通过索引访问元素:列表和元组的索引从 0 开始,可通过索引获取对应位置的元素。例如:
my_list = [1, 2, 3]
print(my_list[0])  # 输出 1
my_tuple = (1, 2, 3)
print(my_tuple[0])  # 输出 1

 

  • slice 切片:使用切片操作获取序列的子序列,可指定起始、结束和步长。例如:
my_list = [1, 2, 3, 4, 5]
print(my_list[1:3])  # 输出 [2, 3]

 

  • 查找与计数
    • 使用index()方法查找元素首次出现的索引,例如:
my_list = [1, 2, 3, 2]
print(my_list.index(2))  # 输出 1

 

  • 使用count()方法统计元素出现的次数,例如:
my_list = [1, 2, 3, 2]
print(my_list.count(2))  # 输出 2

 

  • 最大值、最小值和长度
    • 通过内置函数max()min()获取序列中的最大、最小值,例如:
my_list = [1, 2, 3]
print(max(my_list))  # 输出 3
print(min(my_list))  # 输出 1

 

  • 使用len()函数获取序列的长度,例如:
my_list = [1, 2, 3]
print(len(my_list))  # 输出 3

 

  • 加法、乘法和成员运算
    • 加法:用于连接两个序列,例如:
list1 = [1, 2]
list2 = [3, 4]
print(list1 + list2)  # 输出 [1, 2, 3, 4]

 

  • 乘法:用于重复序列,例如:
list1 = [1, 2]
print(list1 * 3)  # 输出 [1, 2, 1, 2, 1, 2]

 

  • 成员运算:使用innot in判断元素是否在序列中,例如:
my_list = [1, 2, 3]
print(2 in my_list)  # 输出 True

 

  • 序列封包和序列解包
    • 封包:将多个值打包成一个序列,例如packed = 1, 2, 3
    • 解包:将序列中的值分别赋给多个变量,例如:
a, b, c = (1, 2, 3)
print(a, b, c)  # 输出 1 2 3

3.3 列表

  • 创建列表
    • 除了直接使用方括号创建,还可使用列表生成式创建。例如:
my_list = [i for i in range(5)]
print(my_list)  # 输出 [0, 1, 2, 3, 4]

 

  • 增加元素
    • 使用append()方法在列表末尾添加单个元素,例如:
my_list = [1, 2]
my_list.append(3)
print(my_list)  # 输出 [1, 2, 3]

 

  • 使用extend()方法合并另一个列表,例如:
list1 = [1, 2]
list2 = [3, 4]
list1.extend(list2)
print(list1)  # 输出 [1, 2, 3, 4]

 

  • 使用insert()方法在指定位置插入元素,例如:
my_list = [1, 2, 3]
my_list.insert(1, 4)
print(my_list)  # 输出 [1, 4, 2, 3]

 

  • 删除元素
    • 使用del语句删除指定索引的元素,例如:
my_list = [1, 2, 3]
del my_list[0]
print(my_list)  # 输出 [2, 3]

 

  • 使用remove()方法删除指定值的元素,例如:
my_list = [1, 2, 3]
my_list.remove(2)
print(my_list)  # 输出 [1, 3]

 

  • 使用pop()方法弹出并返回指定索引的元素(默认最后一个),例如:
my_list = [1, 2, 3]
popped = my_list.pop()
print(popped)  # 输出 3
print(my_list)  # 输出 [1, 2]

 

  • 逆序和排序
    • 使用reverse()方法将列表元素逆序,例如:
my_list = [1, 2, 3]
my_list.reverse()
print(my_list)  # 输出 [3, 2, 1]

 

  • 使用sort()方法对列表进行排序(默认升序),也可指定reverse=True进行降序排序,例如:
my_list = [3, 1, 2]
my_list.sort()
print(my_list)  # 输出 [1, 2, 3]
my_list.sort(reverse=True)
print(my_list)  # 输出 [3, 2, 1]

 

  • 弹出元素pop()方法可用于获取并移除列表中的元素,常用于栈操作。
  • 浅拷贝和深拷贝
    • 浅拷贝:如new_list = old_list.copy(),只复制顶层元素,对于嵌套列表,只复制引用。例如
import copy
old_list = [[1, 2], [3, 4]]
new_list = old_list.copy()
old_list[0][0] = 5
print(new_list)  # 输出 [[5, 2], [3, 4]]

 

  • 深拷贝:使用copy.deepcopy(),会递归复制所有层次的元素。例如:
import copy
old_list = [[1, 2], [3, 4]]
new_list = copy.deepcopy(old_list)
old_list[0][0] = 5
print(new_list)  # 输出 [[1, 2], [3, 4]]

3.4 元组

  • 创建元组:可使用圆括号或省略括号创建,例如:
my_tuple1 = (1, 2, 3)
my_tuple2 = 1, 2, 3

 

  • 列表和元组之间的转换
    • 使用list()函数可将元组转换为列表,例如:
my_tuple = (1, 2, 3)
my_list = list(my_tuple)
print(my_list)  # 输出 [1, 2, 3]

 

  • 使用tuple()函数可将列表转换为元组,例如:
my_list = [1, 2, 3]
my_tuple = tuple(my_list)
print(my_tuple)  # 输出 (1, 2, 3)

3.5 字典

  • 创建字典:使用花括号{}dict()函数创建字典,例如:
my_dict1 = {'name': 'Tom', 'age': 20}
my_dict2 = dict(name='Tom', age=20)

 

  • 访问元素
    • 通过键来访问对应的值,例如:
my_dict = {'name': 'Tom', 'age': 20}
print(my_dict['name'])  # 输出 Tom

 

  • 也可使用get()方法,该方法在键不存在时可返回默认值,例如:
my_dict = {'name': 'Tom', 'age': 20}
print(my_dict.get('gender', 'unknown'))  # 输出 unknown

 

  • 增加、修改元素:通过赋值语句添加新键值对或修改已有键对应的值,例如:
my_dict = {'name': 'Tom', 'age': 20}
my_dict['gender'] = 'male'  # 增加新键值对
my_dict['age'] = 21  # 修改已有键的值
print(my_dict)  # 输出 {'name': 'Tom', 'age': 21, 'gender': 'male'}

 

  • 删除元素
    • 使用del语句删除指定键值对,例如:
my_dict = {'name': 'Tom', 'age': 20}
del my_dict['age']
print(my_dict)  # 输出 {'name': 'Tom'}

 

  • 使用pop()方法删除指定键的元素并返回其值,例如:
my_dict = {'name': 'Tom', 'age': 20}
age = my_dict.pop('age')
print(age)  # 输出 20
print(my_dict)  # 输出 {'name': 'Tom'}

 

  • 使用popitem()方法随机删除并返回一个键值对(Python 3.7+ 按插入顺序),例如:
my_dict = {'name': 'Tom', 'age': 20}
item = my_dict.popitem()
print(item)  # 输出 ('age', 20)
print(my_dict)  # 输出 {'name': 'Tom'}

 

  • get () 方法和 items () 方法
    • get()方法已介绍,用于安全地获取键对应的值。
    • items()方法返回包含所有键值对的可迭代对象,便于遍历字典,例如:
my_dict = {'name': 'Tom', 'age': 20}
for key, value in my_dict.items():print(key, value)

 

  • keys () 方法和 values () 方法
    • keys()方法返回包含所有键的可迭代对象,例如:
my_dict = {'name': 'Tom', 'age': 20}
print(list(my_dict.keys()))  # 输出 ['name', 'age']

 

  • values()方法返回包含所有值的可迭代对象,例如:
my_dict = {'name': 'Tom', 'age': 20}
print(list(my_dict.values()))  # 输出 ['Tom', 20]

 

  • 字典长度和字典检索
    • 使用len()函数获取字典中键值对的数量,例如:
my_dict = {'name': 'Tom', 'age': 20}
print(len(my_dict))  # 输出 2

 

  • 可通过遍历或直接访问键来检索字典中的数据。
  • update () 方法:用于合并另一个字典或可迭代的键值对到当前字典中,例如:
dict1 = {'name': 'Tom', 'age': 20}
dict2 = {'gender': 'male'}
dict1.update(dict2)
print(dict1)  # 输出 {'name': 'Tom', 'age': 20, 'gender': 'male'}

3.6 其他数据结构

  • 双端队列collections模块中的deque类实现双端队列,支持在两端高效地插入和删除元素。示例代码如下:
from collections import deque
d = deque([1, 2, 3])
d.appendleft(0)  # 在左端添加元素
d.pop()  # 从右端移除元素
print(d)  # 输出 deque([0, 1, 2])

 

  • 堆(优先队列)heapq模块提供了堆相关的操作,可用于实现优先队列,元素按照特定的优先级顺序出队。示例代码如下:
import heapq
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)
print(heapq.heappop(heap))  # 输出 1

第 4 章 流程控制

4.1 分支结构

  • 三种分支结构
    • 单分支:使用if语句,根据条件判断是否执行代码块。例如:
x = 10
if x > 5:print("x 大于 5")

 

  • 双分支:使用if - else语句,根据条件判断执行不同的代码块。例如:
x = 3
if x > 5:print("x 大于 5")
else:print("x 小于等于 5")

 

  • 多分支:使用if - elif - else语句,根据不同的条件判断执行不同的代码块。例如:
x = 7
if x < 5:print("x 小于 5")
elif x < 10:print("x 大于等于 5 且小于 10")
else:print("x 大于等于 10")

 

  • if 语句需要注意的问题
    • 条件表达式的结果应为布尔值。
    • 注意缩进规范,Python 使用缩进来表示代码块,缩进错误会导致逻辑错误。

4.2 循环结构

  • while 循环:只要条件为真,就重复执行循环体中的代码。例如:
i = 0
while i < 5:print(i)i += 1

要注意避免死循环,即条件永远为真的情况。

 

  • for 循环:可用于遍历序列(如列表、字符串)或可迭代对象(如字典的键值对),按顺序执行循环体。例如:
my_list = [1, 2, 3]
for item in my_list:print(item)

 

  • 综合实例:统计数字出现的次数:通过循环遍历数据,统计特定数字出现的频率。示例代码如下:
data = [1, 2, 3, 2, 1, 4, 2]
count_dict = {}
for num in data:if num in count_dict:count_dict[num] += 1else:count_dict[num] = 1
print(count_dict)

 

  • break 和 continue 语句
    • break语句用于跳出当前循环,例如:
for i in range(5):if i == 3:breakprint(i)

 

  • continue语句用于跳过本次循环的剩余代码,继续下一次循环,例如:
for i in range(5):if i == 3:continueprint(i)

 

  • while else 和 for else 语句:当循环正常结束(没有被break中断)时,执行else子句中的代码。例如:
for i in range(5):print(i)
else:print("循环正常结束")

4.3 列表生成式

列表生成式是一种简洁的创建列表的方式,语法为[expression for item in iterable if condition]。例如:

my_list = [i for i in range(5) if i % 2 == 0]
print(my_list)  # 输出 [0, 2, 4]

4.4 生成器

生成器是一种特殊的迭代器,通过生成器表达式(如(i for i in range(5)))或函数中使用yield语句创建,可实现惰性求值,节省内存。示例代码如下:

# 生成器表达式
gen = (i for i in range(5))
for item in gen:print(item)# 生成器函数
def my_generator():for i in range(5):yield igen = my_generator()
for item in gen:print(item)

4.5 迭代器

迭代器是实现了__iter__()__next__()方法的对象,可用于遍历数据。文件对象、range()函数返回的对象等都是迭代器。示例代码如下:

my_list = [1, 2, 3]
my_iter = iter(my_list)
print(next(my_iter))  # 输出 1
print(next(my_iter))  # 输出 2
print(next(my_iter))  # 输出 3

4.6 安全专题

4.6.1 破解 MD5:MD5 是一种广泛使用的哈希算法,但它存在安全性缺陷,容易受到碰撞攻击。在 Python 中,可以使用hashlib库进行 MD5 计算。虽然不能直接破解复杂的 MD5 哈希值,但通过字典攻击等方法,可以尝试破解简单的 MD5 加密密码。例如:

import hashlibpassword = "test"
hash_object = hashlib.md5(password.encode())
hash_value = hash_object.hexdigest()
# 通过构建密码字典,对比哈希值进行破解尝试

4.6.2 凯撒密码:凯撒密码是一种简单的替换加密技术,通过将明文中的每个字母按照一定的偏移量进行替换来生成密文。在 Python 中实现凯撒密码加解密的代码如下:

def caesar_encrypt(text, shift):result = ""for char in text:if char.isalpha():start = ord('A') if char.isupper() else ord('a')result += chr((ord(char) - start + shift) % 26 + start)else:result += charreturn resultdef caesar_decrypt(text, shift):return caesar_encrypt(text, -shift)

 

4.6.3 仿射密码:仿射密码基于数学原理,使用线性变换对明文字符进行加密。其加密公式为E(x) = (ax + b) mod 26,解密公式为D(x) = a⁻¹(x - b) mod 26,其中a26互质。在 Python 中实现仿射密码的代码如下:

def gcd(a, b):while b!= 0:a, b = b, a % breturn adef mod_inverse(a, m):for x in range(1, m):if (a * x) % m == 1:return xreturn Nonedef affine_encrypt(text, a, b):result = ""for char in text:if char.isalpha():start = ord('A') if char.isupper() else ord('a')result += chr((a * (ord(char) - start) + b) % 26 + start)else:result += charreturn resultdef affine_decrypt(text, a, b):a_inv = mod_inverse(a, 26)result = ""for char in text:if char.isalpha():start = ord('A') if char.isupper() else ord('a')result += chr((a_inv * (ord(char) - start - b)) % 26 + start)else:result += charreturn result

第 5 章 函数和模块

5.1 函数的定义和调用

  • 5.1.1 函数的定义方式:使用def关键字定义函数,函数可以包含参数和返回值。例如,定义一个计算两个数之和的函数:
def add(a, b):return a + b

 

  • 5.1.2 函数说明文档:在函数定义的开头使用三引号"""添加文档字符串,用于描述函数的功能、参数和返回值等信息。例如:
def add(a, b):"""计算两个数的和。:param a: 第一个数:param b: 第二个数:return: 两数之和"""return a + b

 

  • 5.1.3 返回值:函数可通过return语句返回一个或多个值。当没有return语句时,函数默认返回None。例如,返回多个值的函数:
def divmod_custom(a, b):return a // b, a % b

 

  • 5.1.4 函数的嵌套:函数内部可以定义另一个函数,内部函数可以访问外部函数的变量。例如:
def outer_function(x):def inner_function(y):return x + yreturn inner_function

 

  • 5.1.5 函数执行的起点:Python 程序从main函数或脚本的第一行可执行代码开始执行,函数在被调用时才执行其内部代码。可以通过if __name__ == '__main__':来控制代码的执行逻辑。

5.2 函数的参数

  • 5.2.1 位置参数:按照参数定义的顺序传递参数,实参和形参一一对应。例如:
def greet(name, age):print(f"你好,{name},你{age}岁了。")greet("张三", 20)

 

  • 5.2.2 默认参数:在函数定义时为参数指定默认值,调用函数时若不传递该参数,则使用默认值。例如:
def greet(name, age=18):print(f"你好,{name},你{age}岁了。")greet("李四")

 

  • 5.2.3 可变参数*args用于接收任意数量的非关键字参数,将其打包成元组;**kwargs用于接收任意数量的关键字参数,将其打包成字典。例如:
def print_info(*args, **kwargs):print("非关键字参数:", args)print("关键字参数:", kwargs)

 

  • 5.2.4 关键字参数:调用函数时通过参数名指定参数值,可打破位置参数的顺序限制。例如:
def greet(name, age):print(f"你好,{name},你{age}岁了。")greet(age=25, name="王五")

 

  • 5.2.5 命名关键字:在函数定义中使用*分隔普通参数和命名关键字参数,命名关键字参数必须以指定的参数名传递。例如:
def func(a, b, *, c, d):print(a, b, c, d)

 

  • 5.2.6 综合实例:以一个简单的学生信息管理函数为例,展示不同参数类型的综合使用:
def manage_student(name, age, *scores, major="计算机科学", **info):print(f"姓名: {name},年龄: {age},专业: {major}")print("成绩:", scores)print("其他信息:", info)

 

  • 5.2.7 函数参数传递机制:Python 中,对于不可变对象(如数字、字符串、元组),函数参数传递采用值传递;对于可变对象(如列表、字典),采用引用传递。理解这一机制有助于避免在函数调用过程中出现意外的数据修改。

5.3 lambda 表达式

lambda 表达式是一种匿名函数,语法简洁,适用于简单的函数逻辑。例如,定义一个计算两数之和的 lambda 函数

add = lambda x, y: x + y

 

lambda 函数常作为参数传递给其他高阶函数,如sortedmapfilter等。

5.4 变量的作用域和命名空间

变量的作用域决定了变量在程序中的可见范围,命名空间是一个保存变量名到对象映射的地方。Python 中有全局命名空间、局部命名空间等。理解变量的作用域和命名空间,有助于避免变量命名冲突,提高代码的可读性和可维护性。

5.5 函数高级特性

  • 5.5.1 生成器函数:包含yield语句的函数就是生成器函数,调用时返回一个生成器对象。生成器函数可以迭代产生值,实现惰性求值。例如,前面提到的斐波那契数列生成器函数。
  • 5.5.2 高阶函数:接受函数作为参数或返回值为函数的函数称为高阶函数。mapfilterreduce等都是常见的高阶函数。例如,使用map函数对列表中的每个元素进行平方运算:
my_list = [1, 2, 3, 4]
result = list(map(lambda x: x ** 2, my_list))

 

  • 5.5.3 偏函数:使用functools.partial()创建偏函数,固定函数的部分参数,返回一个新的函数。例如,创建一个默认底数为 2 的幂运算偏函数:
from functools import partial
power = partial(pow, 2)

 

  • 5.5.4 修饰器(装饰器):装饰器用于修改或增强函数的功能,通过@符号应用。例如,使用装饰器实现函数调用日志记录:
def log(func):def wrapper(*args, **kwargs):print(f"调用函数: {func.__name__}")return func(*args, **kwargs)return wrapper@log
def add(a, b):return a + b

5.6 模块化编程

  • 5.6.1 内置模块:Python 自带了众多内置模块,如mathrandomdatetime等,可直接导入使用。例如,使用math模块计算平方根:
import math
print(math.sqrt(16))

 

  • 5.6.2 安装第三方模块:使用pipconda安装第三方库。例如,使用pip install requests安装用于 HTTP 请求的requests库。
  • 5.6.3 自定义模块:将相关的函数、类等组织在一个.py文件中,创建自定义模块。例如,创建一个my_module.py文件,包含一些自定义函数,然后通过import语句导入使用。
  • 5.6.4 模块导入顺序:一般按照内置模块、第三方模块、自定义模块的顺序导入,避免命名冲突。在导入模块时,可以使用as关键字为模块指定别名。

5.7 PyInstaller 打包

使用 PyInstaller 工具将 Python 脚本打包成可执行文件,方便在没有 Python 环境的机器上运行。例如,使用pyinstaller my_script.py命令进行打包,支持 Windows、Linux、Mac OS 等不同操作系统。

5.8 安全专题

  • 5.8.1 摘要算法的雪崩效应:摘要算法(如 MD5、SHA - 1 等)的雪崩效应指输入的微小变化会导致输出的巨大变化。通过实验可以验证这一特性,例如,使用hashlib库计算两个只有一位不同的字符串的哈希值,对比结果可以明显看出雪崩效应。
    import hashlib# 定义两个只有一位不同的字符串
    str1 = "hello world"
    str2 = "hello worle"# 创建SHA - 256哈希对象并计算哈希值
    hash1 = hashlib.sha256(str1.encode()).hexdigest()
    hash2 = hashlib.sha256(str2.encode()).hexdigest()print(f"字符串1: {str1} 的哈希值: {hash1}")
    print(f"字符串2: {str2} 的哈希值: {hash2}")

     

  • 5.8.2 AES 算法的雪崩效应:AES 加密算法也具有雪崩效应。在 Python 中,可以使用pycryptodome库进行 AES 加密实验,通过改变明文的一位,观察密文的变化,分析雪崩效应在 AES 加密安全性中的作用。
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad, unpad
    import binasciidef aes_encrypt(plaintext, key):cipher = AES.new(key.encode('utf - 8'), AES.MODE_CBC)ct_bytes = cipher.encrypt(pad(plaintext.encode('utf - 8'), AES.block_size))iv = cipher.ivreturn iv + ct_bytesdef aes_decrypt(ct, key):iv = ct[:AES.block_size]ct = ct[AES.block_size:]cipher = AES.new(key.encode('utf - 8'), AES.MODE_CBC, iv)pt = unpad(cipher.decrypt(ct), AES.block_size)return pt.decode('utf - 8')# 定义密钥
    key = "1234567890123456"
    # 定义两个只有一位不同的明文
    plaintext1 = "hello world"
    plaintext2 = "hello worle"# 加密明文
    ciphertext1 = aes_encrypt(plaintext1, key)
    ciphertext2 = aes_encrypt(plaintext2, key)print(f"明文1: {plaintext1} 的密文: {binascii.hexlify(ciphertext1).decode()}")
    print(f"明文2: {plaintext2} 的密文: {binascii.hexlify(ciphertext2).decode()}")

     

第 6 章 文件操作和异常处理

6.1 读、写文本文件

  • 6.1.1 读取文本文件
    • open()函数是 Python 中用于打开文件的内置函数,当以读取模式'r'打开文件时,它会返回一个文件对象。例如:file = open('example.txt', 'r'),这里'example.txt'是文件名,需要确保该文件在正确的路径下,否则会抛出FileNotFoundError异常。
    • read()方法用于一次性读取文件的全部内容,并返回一个字符串。例如:content = file.read()
    • readline()方法每次读取文件的一行内容,返回一个字符串。可以通过循环多次调用readline()来逐行读取文件:
file = open('example.txt', 'r')
while True:line = file.readline()if not line:breakprint(line.strip())  # strip()方法用于去除行末的换行符
file.close()
  • readlines()方法会读取文件的所有行,并将每一行作为一个元素存储在一个列表中。例如:lines = file.readlines()
  • 读取完文件后,需要使用close()方法关闭文件,以释放系统资源。更好的做法是使用with语句,它会在代码块结束后自动关闭文件,示例如下:

 

python

with open('example.txt', 'r') as file:content = file.read()

 

  • 6.1.2 写入文本文件
    • 'w'模式打开文件时,如果文件不存在则创建一个新文件,如果文件已存在则会覆盖原有内容。例如:file = open('output.txt', 'w')
    • 'a'模式打开文件时,用于追加内容到文件末尾。例如:file = open('output.txt', 'a')
    • write()方法用于将一个字符串写入文件中。例如:file.write("Hello, World!\n"),这里\n表示换行符。
    • writelines()方法用于写入一个字符串列表到文件中。需要注意的是,该方法不会自动添加换行符,所以如果需要换行,需要在每个字符串末尾手动添加。例如:

 

python

lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
with open('output.txt', 'w') as file:file.writelines(lines)

 

  • 6.1.3 读、写二进制文件
    • 当处理图片、音频、视频等非文本文件时,需要使用'rb'(读二进制)和'wb'(写二进制)模式。例如,读取一个图片文件:

 

python

with open('image.jpg', 'rb') as file:binary_data = file.read()

 

  • 写入二进制文件的操作类似,例如将读取的二进制数据写入另一个文件:

 

python

with open('new_image.jpg', 'wb') as file:file.write(binary_data)

6.2 举例

  • 6.2.1 统计字母出现的次数
letter_count = {}
with open('text.txt', 'r') as file:content = file.read()for char in content:if char.isalpha():letter_count[char] = letter_count.get(char, 0) + 1
for letter, count in letter_count.items():print(f"{letter}: {count}")

 

上述代码中,首先创建一个空字典letter_count用于存储字母及其出现的次数。然后打开文件读取内容,遍历每个字符,如果是字母则更新字典中该字母的计数。

 

  • 6.2.2 拓展
    • 忽略大小写统计可以在处理字符时将其统一转换为大写或小写,例如:
letter_count = {}
with open('text.txt', 'r') as file:content = file.read()for char in content:char = char.lower()  # 转换为小写if char.isalpha():letter_count[char] = letter_count.get(char, 0) + 1
for letter, count in sorted(letter_count.items(), key=lambda item: item[1], reverse=True):print(f"{letter}: {count}")

 

  • 按频率排序可以使用sorted()函数,通过指定key参数来按照值(即字母出现的次数)进行排序。

6.3 jieba 和 wordcloud 库

  • 6.3.1 jieba 库
    • jieba 是一个强大的中文分词工具。精确模式是将句子最精确地切开,适合文本分析;全模式会把句子中所有的可以成词的词语都扫描出来,但可能会有冗余;搜索引擎模式在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
    • 示例代码:
import jiebatext = "我来到北京清华大学"
# 精确模式
seg_list = jieba.cut(text, cut_all=False)
print("精确模式: " + "/ ".join(seg_list))# 全模式
seg_list = jieba.cut(text, cut_all=True)
print("全模式: " + "/ ".join(seg_list))# 搜索引擎模式
seg_list = jieba.cut_for_search(text)
print("搜索引擎模式: " + "/ ".join(seg_list))

 

  • 6.3.2 wordcloud 库
    • wordcloud 库可以根据文本中词语的频率生成词云图。在生成词云图时,可以设置字体(如font_path参数)、颜色(color_func参数)、形状(通过mask参数设置一个图片作为词云的形状)等样式。
    • 示例代码:
from wordcloud import WordCloud
import matplotlib.pyplot as plttext = "Python是一种非常强大的编程语言,广泛应用于数据科学、人工智能等领域"
wordcloud = WordCloud(background_color="white").generate(text)
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()

 

  • 6.3.3 2023 年政府工作报告词云
    • 首先需要获取 2023 年政府工作报告的文本内容(可以从官方渠道获取),然后结合 jieba 库进行分词,再使用 wordcloud 库生成词云图。示例代码(假设已经获取了文本内容存储在report.txt文件中):
import jieba
from wordcloud import WordCloud
import matplotlib.pyplot as pltwith open('report.txt', 'r', encoding='utf-8') as file:text = file.read()
words = jieba.lcut(text)
text = " ".join(words)
wordcloud = WordCloud(background_color="white", font_path='simhei.ttf').generate(text)
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()

 

这里使用simhei.ttf字体文件来正确显示中文,需要确保该字体文件在正确的路径下。

6.4 读写 CSV 文件

  • 6.4.1 CSV 模块
    • Python 内置的csv模块提供了处理 CSV 文件的功能。csv.reader()函数用于读取 CSV 文件,它返回一个可迭代的对象,每一行数据作为一个列表。例如:
import csv
with open('data.csv', 'r') as file:reader = csv.reader(file)for row in reader:print(row)

 

  • csv.writer()函数用于写入 CSV 文件,需要传入一个文件对象。使用writerow()方法可以写入一行数据(以列表形式)。例如:
import csv
data = [["Name", "Age"], ["Alice", 25], ["Bob", 30]]
with open('output.csv', 'w', newline='') as file:writer = csv.writer(file)for row in data:writer.writerow(row)

 

这里newline=''是为了避免在 Windows 系统下写入 CSV 文件时出现空行问题。

 

  • 6.4.2 举例
    • 读取包含学生成绩的 CSV 文件并进行处理,例如计算平均分:
import csv
total_score = 0
count = 0
with open('scores.csv', 'r') as file:reader = csv.reader(file)next(reader)  # 跳过表头for row in reader:score = float(row[1])  # 假设成绩在第二列total_score += scorecount += 1
if count > 0:average_score = total_score / countprint(f"平均成绩: {average_score}")

 

  • 将处理后的数据写入新的 CSV 文件,例如将学生成绩进行某种转换后写入:
import csv
new_data = []
with open('scores.csv', 'r') as file:reader = csv.reader(file)header = next(reader)new_data.append(header)for row in reader:new_score = float(row[1]) * 1.1  # 假设将成绩提高10%new_row = [row[0], new_score]new_data.append(new_row)
with open('new_scores.csv', 'w', newline='') as file:writer = csv.writer(file)for row in new_data:writer.writerow(row)

6.5 读写 JSON 文件

  • 6.5.1 序列化
    • 序列化是将 Python 对象(如字典、列表)转换为 JSON 格式的字符串的过程。使用json.dumps()方法可以实现这一功能。例如:
import json
data = {"name": "Alice", "age": 25}
json_str = json.dumps(data)
print(json_str)

 

  • 6.5.2 JSON 模块
    • json模块的loads()方法用于将 JSON 格式的字符串反序列化为 Python 对象。例如:
import json
json_str = '{"name": "Alice", "age": 25}'
data = json.loads(json_str)
print(data)

 

这在不同系统和语言之间进行数据交换时非常有用,因为 JSON 是一种通用的数据格式。

6.6 文件目录相关操作

  • 6.6.1 os 模块以及 os.path
    • os模块提供了许多与操作系统进行交互的功能,如创建、删除文件和目录,获取文件和目录信息等。os.path子模块则专注于处理文件路径相关的操作。
    • os.path.join()函数用于拼接文件路径,它会根据操作系统的不同自动使用正确的路径分隔符。例如:path = os.path.join('folder1', 'folder2', 'file.txt')
    • os.path.exists()函数用于判断一个路径是否存在。例如:if os.path.exists('example.txt'):
  • 6.6.2 目录遍历的三种方式
    • 使用os.listdir()结合递归:os.listdir()函数返回指定目录下的所有文件和文件夹名称。结合递归可以遍历子目录。示例代码:
import osdef traverse_directory(directory):for item in os.listdir(directory):item_path = os.path.join(directory, item)if os.path.isdir(item_path):traverse_directory(item_path)else:print(item_path)traverse_directory('.')  # 遍历当前目录

 

  • 使用os.walk()os.walk()函数会递归地遍历目录树,返回一个三元组(dirpath, dirnames, filenames),其中dirpath是当前目录路径,dirnames是当前目录下的子目录名称列表,filenames是当前目录下的文件名称列表。示例代码:
import osfor dirpath, dirnames, filenames in os.walk('.'):for file in filenames:file_path = os.path.join(dirpath, file)print(file_path)

 

  • 使用pathlib模块(Python 3.4+):pathlib提供了面向对象的方式来处理文件路径和目录操作。示例代码:
from pathlib import Pathfor item in Path('.').rglob('*'):if item.is_file():print(item)

6.7 异常处理

  • 6.7.1 Python 中的异常类
    • ZeroDivisionError:当尝试除以零时会抛出该异常。例如:result = 1 / 0会引发ZeroDivisionError
    • FileNotFoundError:当尝试打开一个不存在的文件时会抛出该异常。例如:file = open('nonexistent.txt', 'r')会引发FileNotFoundError
    • 还有许多其他的异常类,如TypeError(类型错误)、IndexError(索引错误)等,了解这些异常类有助于在编程中进行错误处理。
  • 6.7.2 捕获和处理异常
    • 使用try - except语句块可以捕获可能出现的异常。例如:
try:file = open('example.txt', 'r')content = file.read()file.close()
except FileNotFoundError:print("文件不存在")

 

  • 可以使用多个except子句来针对不同类型的异常进行处理。例如:
try:num = 1 / 0file = open('example.txt', 'r')
except ZeroDivisionError:print("除数不能为零")
except FileNotFoundError:print("文件不存在")

 

  • 6.7.3 raise 语句
    • raise语句用于主动抛出异常。例如,当函数的输入不符合要求时,可以抛出异常:
def divide(a, b):if b == 0:raise ZeroDivisionError("除数不能为零")return a / b

 

  • 6.7.4 排查异常和记录异常
    • Python 的调试工具(如pdb模块)可以帮助排查异常发生的位置和原因。pdb提供了交互式的调试环境,可以逐行执行代码,查看变量的值等。
    • 使用logging模块可以记录异常信息。例如:
import loggingtry:num = 1 / 0
except ZeroDivisionError as e:logging.error(f"发生异常: {e}", exc_info=True)

 

exc_info=True参数会将异常的详细信息记录下来,便于后续分析和修复。

6.8 综合实例:网络爬虫

  • 6.8.1 爬取热榜榜单
    • 首先需要使用requests库发送 HTTP 请求获取网页内容。例如:
import requestsurl = "https://example.com/hotlist"
response = requests.get(url)
if response.status_code == 200:html_content = response.text
else:print(f"请求失败,状态码: {response.status_code}")

 

  • 然后使用BeautifulSouplxml等库解析网页。以BeautifulSoup为例:
from bs4 import BeautifulSoupsoup = BeautifulSoup(html_content, 'html.parser')
# 假设新闻标题在 <h2 class="title"> 标签中,播放量在 <span class="views"> 标签中
titles = soup.find_all('h2', class_='title')
views = soup.find_all('span', class_='views')
for title, view in zip(titles, views):print(f"新闻标题: {title.text.strip()}, 播放量: {view.text.strip()}")

 

  • 6.8.2 爬取多个榜单
    • 可以通过修改 URL 和解析逻辑来爬取多个不同类型的榜单。例如,爬取音乐榜单和影视榜单:
import requests
from bs4 import BeautifulSoup# 爬取音乐榜单
music_url = "https://example.com/musiclist"
music_response = requests.get(music_url)
if music_response.status_code == 200:music_html = music_response.textmusic_soup = BeautifulSoup(music_html, 'html.parser')# 解析音乐榜单数据#...# 爬取影视榜单
movie_url = "https://example.com/movielist"
movie_response = requests.get(movie_url)
if movie_response.status_code == 200:movie_html = movie_response.textmovie_soup = BeautifulSoup(movie_html, 'html.parser')# 解析影视榜单数据#...

 

  • 对数据进行整理和存储,可以将数据存储在列表、字典中,或者写入文件、数据库等。

6.9 安全专题

  • 6.9.1 简易病毒扫描
    • 可以事先收集已知的病毒特征代码,存储在一个列表或文件中。然后遍历目标文件的内容,检查是否包含这些特征代码。示例代码(简化版):
def scan_file(file_path, virus_signatures):try:# 以二进制模式打开文件with open(file_path, 'rb') as file:content = file.read()for signature in virus_signatures:# 将病毒特征码编码为字节类型signature_bytes = signature.encode()if signature_bytes in content:print(f"文件 {file_path} 可能包含病毒!")return Trueprint(f"文件 {file_path} 未检测到病毒特征。")return Falseexcept FileNotFoundError:print(f"文件 {file_path} 未找到。")except PermissionError:print(f"没有权限访问文件 {file_path}。")except Exception as e:print(f"扫描文件 {file_path} 时出现错误: {e}")return False# 示例病毒特征码
virus_signatures = ["virus_code_1", "virus_code_2"]
file_path = "test_file.txt"
scan_file(file_path, virus_signatures)

 

  • 6.9.2 大文件的摘要计算
    对于大文件,一次性将其全部读入内存来计算摘要可能会导致内存不足。因此,需要分块读取文件内容进行哈希计算。以下是使用hashlib库计算大文件 MD5 和 SHA - 256 摘要的示例代码:
import hashlibdef calculate_file_digest(file_path, algorithm='md5'):if algorithm == 'md5':hash_obj = hashlib.md5()elif algorithm == 'sha256':hash_obj = hashlib.sha256()else:raise ValueError("不支持的哈希算法,仅支持'md5'和'sha256'")try:with open(file_path, 'rb') as file:# 分块读取文件内容for chunk in iter(lambda: file.read(4096), b""):hash_obj.update(chunk)return hash_obj.hexdigest()except FileNotFoundError:print(f"文件 {file_path} 未找到。")except Exception as e:print(f"计算摘要时出现错误: {e}")file_path = 'large_file.zip'
md5_digest = calculate_file_digest(file_path, 'md5')
sha256_digest = calculate_file_digest(file_path, 'sha256')
print(f"MD5摘要: {md5_digest}")
print(f"SHA - 256摘要: {sha256_digest}")

第 7 章 面向对象程序设计

7.1 类和对象

  • 7.1.1 定义类和创建对象
    在 Python 中,使用class关键字定义类,类可以包含属性和方法。例如,定义一个简单的Person类:
class Person:def __init__(self, name, age):self.name = nameself.age = agedef introduce(self):print(f"我叫 {self.name},今年 {self.age} 岁。")# 创建对象
person1 = Person("Alice", 25)
person1.introduce()

 

这里__init__是类的构造方法,用于初始化对象的属性。self代表类的实例对象,在类的方法中必须作为第一个参数。

  • 7.1.2 访问可见性
    Python 没有严格意义上的私有属性和方法,但通过命名约定来限制访问。以单下划线_开头的属性和方法被视为受保护的,通常表示这些属性和方法不应该在类外部直接访问,但实际上还是可以访问的。以双下划线__开头的属性和方法被视为私有的,Python 会对其进行名称修饰,使得外部不能直接访问。示例如下:
class MyClass:def __init__(self):self._protected_attr = 10self.__private_attr = 20def _protected_method(self):print("这是一个受保护的方法。")def __private_method(self):print("这是一个私有方法。")obj = MyClass()
print(obj._protected_attr)  # 可以访问,但不建议
obj._protected_method()  # 可以调用,但不建议# 尝试直接访问私有属性和方法会报错
# print(obj.__private_attr)  
# obj.__private_method()  # 可以通过名称修饰后的名称访问私有属性和方法
print(obj._MyClass__private_attr)
obj._MyClass__private_method()

 

  • 7.1.3 类属性和实例属性
    类属性是属于类的属性,所有实例共享该属性;实例属性是每个实例单独拥有的属性,通过self关键字在方法中访问。示例如下:
class Dog:# 类属性species = "犬科"def __init__(self, name):# 实例属性self.name = namedog1 = Dog("旺财")
dog2 = Dog("来福")print(f"{dog1.name} 属于 {dog1.species}")
print(f"{dog2.name} 属于 {dog2.species}")# 修改类属性
Dog.species = "哺乳动物"
print(f"{dog1.name} 属于 {dog1.species}")
print(f"{dog2.name} 属于 {dog2.species}")

 

7.2 方法

  • 7.2.1 构造方法和析构方法
    • __init__()是构造方法,在创建对象时自动调用,用于初始化对象的属性。例如前面的Person类中的__init__方法。
    • __del__()是析构方法,在对象被销毁时调用,可用于资源清理。示例如下:
class ResourceManager:def __init__(self, resource):self.resource = resourceprint(f"获取资源: {self.resource}")def __del__(self):print(f"释放资源: {self.resource}")res = ResourceManager("文件资源")
del res  # 手动删除对象,触发析构方法

 

  • 7.2.2 类方法和静态方法
    • 类方法使用@classmethod装饰器定义,第一个参数为类本身(通常用cls表示),可访问类属性。示例如下:
class Rectangle:width = 0height = 0def __init__(self, width, height):self.width = widthself.height = height@classmethoddef set_default_size(cls, width, height):cls.width = widthcls.height = heightdef area(self):return self.width * self.height# 使用类方法设置默认尺寸
Rectangle.set_default_size(5, 10)
rect = Rectangle(3, 4)
print(rect.area())  # 输出: 12
print(Rectangle.width, Rectangle.height)  # 输出: 5 10

 

  • 静态方法使用@staticmethod装饰器定义,不依赖于类和实例,类似普通函数。示例如下:
class MathUtils:@staticmethoddef add(a, b):return a + bresult = MathUtils.add(3, 5)
print(result)  # 输出: 8

 

  • 7.2.3 @property 装饰器
    @property装饰器将方法转换为属性的形式访问,可用于实现属性的 getter、setter 和 deleter 方法,增加属性访问的控制逻辑。示例如下:
class Person:def __init__(self, age):self.__age = age@propertydef age(self):return self.__age@age.setterdef age(self, new_age):if new_age < 0:print("年龄不能为负数。")else:self.__age = new_age@age.deleterdef age(self):del self.__agep = Person(25)
print(p.age)  # 调用getter方法
p.age = 30  # 调用setter方法
print(p.age)
del p.age  # 调用deleter方法
# 此时再访问p.age会报错

7.3 继承和多态

  • 7.3.1 继承
    继承是面向对象编程的重要特性,子类可以继承父类的属性和方法。通过在类定义中指定父类(例如class SubClass(SuperClass):)来实现继承。子类可以重写父类的方法以满足自身的特定需求。例如:
class Animal:def __init__(self, name):self.name = namedef speak(self):print(f"{self.name} 发出声音")class Dog(Animal):def speak(self):print(f"{self.name} 汪汪叫")class Cat(Animal):def speak(self):print(f"{self.name} 喵喵叫")animal = Animal("动物")
dog = Dog("小狗")
cat = Cat("小猫")animal.speak()
dog.speak()
cat.speak()

 

在上述代码中,Dog类和Cat类继承自Animal类,并且重写了speak方法,使得不同的子类对象能够表现出不同的行为。

  • 7.3.2 MixIn
    MixIn 是一种特殊的多重继承方式,通常用于为多个类混入额外的功能,而不涉及复杂的继承层次结构。它的主要目的是为了代码的复用。例如,假设有一个Flyable MixIn 类和一个Swimmable MixIn 类:
class Flyable:def fly(self):print("我能飞")class Swimmable:def swim(self):print("我能游泳")class Bird(Animal, Flyable):def __init__(self, name):super().__init__(name)class Fish(Animal, Swimmable):def __init__(self, name):super().__init__(name)bird = Bird("麻雀")
fish = Fish("金鱼")bird.speak()
bird.fly()
fish.speak()
fish.swim()

 

在这个例子中,Bird类继承了Animal类和Flyable MixIn 类,从而拥有了Animal类的属性和方法以及Flyable类的fly方法;Fish类继承了Animal类和Swimmable MixIn 类,拥有了Animal类的属性和方法以及Swimmable类的swim方法。

  • 7.3.3 多态
    多态是指不同类的对象对同一消息(方法调用)作出不同的响应。在前面的继承例子中,Animal类、Dog类和Cat类都有speak方法,但它们的实现不同。当通过不同的对象调用speak方法时,会执行相应类中的speak方法,这就是多态的体现。多态提高了代码的灵活性和可扩展性,使得代码可以更方便地处理不同类型的对象。

7.4 动态属性和 slots

  • 7.4.1 动态属性
    在 Python 中,对象在运行时可以动态添加属性。例如:
class MyObject:def __init__(self):self.x = 10obj = MyObject()
obj.y = 20  # 动态添加属性y
print(obj.x, obj.y)

然而,动态添加属性可能会导致内存消耗增加,因为 Python 需要额外的空间来存储这些动态属性。同时,也可能会使代码难以维护,因为属性的定义和使用可能比较分散。

  • 7.4.2 slots
    在类中定义__slots__属性可以限制实例可以拥有的属性,从而节省内存空间,提高程序性能。__slots__定义了一个元组,其中包含了允许实例拥有的属性名称。例如:
class MyClass:__slots__ = ('x', 'y')def __init__(self):self.x = 10self.y = 20obj = MyClass()
print(obj.x, obj.y)
# 尝试添加新的属性会报错
# obj.z = 30

在上述代码中,MyClass类定义了__slots__属性,只允许实例拥有xy两个属性,当尝试添加新的属性z时会引发错误。

7.5 定制类和重载运算符

  • 7.5.1 定制类
    通过定义特殊方法(如__str__()__repr__()等),可以定制类在不同场景下的表现。__str__()方法用于定义对象的字符串表示形式,通常用于打印对象时的输出。__repr__()方法也用于返回对象的字符串表示,但它更侧重于开发者调试和记录,一般要求__repr__()返回的字符串可以用于重新创建对象。例如:
class Point:def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return f"Point({self.x}, {self.y})"def __repr__(self):return f"Point({self.x}, {self.y})"p = Point(1, 2)
print(p)  # 调用__str__方法
print(repr(p))  # 调用__repr__方法

 

  • 7.5.2 重载运算符
    可以重载常见的运算符(如+-*等),使自定义类的对象能够像内置类型一样进行运算。例如,定义一个Vector类并重载+运算符:
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Vector(self.x + other.x, self.y + other.y)def __str__(self):return f"Vector({self.x}, {self.y})"v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2
print(v3)

 

在上述代码中,Vector类的__add__方法定义了+运算符的行为,使得两个Vector对象可以相加并返回一个新的Vector对象。

7.6 综合实例:网络爬虫类

将网络爬虫的相关功能封装成一个类,能够更好地组织和管理代码,体现面向对象编程在实际项目中的应用。以下是一个简单的网络爬虫类示例:

import requests
from bs4 import BeautifulSoupclass WebCrawler:def __init__(self):self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"}def get_page_content(self, url):try:response = requests.get(url, headers=self.headers)if response.status_code == 200:return response.textelse:print(f"请求失败,状态码: {response.status_code}")return Noneexcept requests.RequestException as e:print(f"请求出现异常: {e}")return Nonedef parse_page(self, content):if content:soup = BeautifulSoup(content, 'html.parser')# 这里可以根据具体的网页结构进行解析,例如提取所有的链接links = soup.find_all('a')return [link.get('href') for link in links]return []# 使用示例
crawler = WebCrawler()
url = "https://example.com"
content = crawler.get_page_content(url)
links = crawler.parse_page(content)
print(links)

 

这个WebCrawler类包含了发送 HTTP 请求获取网页内容的get_page_content方法和解析网页内容的parse_page方法,通过实例化该类并调用相应方法,可以实现简单的网络爬虫功能。

7.7 安全专题

  • 7.7.1 AES 算法流程
    高级加密标准(AES)是一种对称加密算法,其加密和解密流程如下:

    • 分组加密:将明文分成固定长度的块(通常为 128 位、192 位或 256 位)。
    • 密钥扩展:根据密钥生成一系列的轮密钥,用于后续的轮函数运算。
    • 初始轮函数:对明文块进行初始的轮函数运算,包括字节替换、行移位、列混合和轮密钥加等操作。
    • 中间轮函数:重复进行轮函数运算,除了最后一轮不进行列混合操作。
    • 最终轮函数:进行最后一轮轮函数运算,得到密文。
      解密过程则是加密过程的逆运算,按照相反的顺序执行相应的操作。
  • 7.7.2 AES 算法实现
    在 Python 中,可以使用pycryptodome库来实现 AES 算法。以下是一个简单的示例代码:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import osdef encrypt_data(key, data):cipher = AES.new(key, AES.MODE_ECB)padded_data = pad(data.encode(), AES.block_size)encrypted_data = cipher.encrypt(padded_data)return encrypted_datadef decrypt_data(key, encrypted_data):cipher = AES.new(key, AES.MODE_ECB)decrypted_data = cipher.decrypt(encrypted_data)unpadded_data = unpad(decrypted_data, AES.block_size)return unpadded_data.decode()# 生成一个16字节的密钥
key = os.urandom(16)
data = "这是一段需要加密的数据"
encrypted = encrypt_data(key, data)
decrypted = decrypt_data(key, encrypted)
print(f"明文: {data}")
print(f"密文: {encrypted.hex()}")
print(f"解密后: {decrypted}")

 

在上述代码中,使用AES.MODE_ECB模式进行加密和解密,padunpad函数用于对数据进行填充和解填充,以满足 AES 算法的要求。

 

  • 7.7.3 AES 加、解密类
    将 AES 算法封装成一个类,方便在安全相关的应用中使用。示例代码如下:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import osclass AESHelper:def __init__(self, key):self.key = keydef encrypt(self, data):cipher = AES.new(self.key, AES.MODE_ECB)padded_data = pad(data.encode(), AES.block_size)encrypted_data = cipher.encrypt(padded_data)return encrypted_datadef decrypt(self, encrypted_data):cipher = AES.new(self.key, AES.MODE_ECB)decrypted_data = cipher.decrypt(encrypted_data)unpadded_data = unpad(decrypted_data, AES.block_size)return unpadded_data.decode()# 使用示例
key = os.urandom(16)
aes = AESHelper(key)
data = "这是一段需要加密的数据"
encrypted = aes.encrypt(data)
decrypted = aes.decrypt(encrypted)
print(f"明文: {data}")
print(f"密文: {encrypted.hex()}")
print(f"解密后: {decrypted}")

这个AESHelper类提供了encryptdecrypt方法,通过实例化该类并传入密钥,可以方便地对数据进行加密和解密操作。

 

第 8 章 多进程和多线程

8.1 多进程

  • 8.1.1 multiprocessing 模块的 Process 类
    在 Python 中,multiprocessing.Process类用于创建新的进程。通过继承Process类并重写其run()方法,可以定义进程执行的具体任务。示例代码如下:
import multiprocessingclass MyProcess(multiprocessing.Process):def run(self):print(f"子进程 {self.name} 正在执行任务")if __name__ == "__main__":p = MyProcess()p.start()p.join()print("主进程继续执行")

在上述代码中,MyProcess类继承自multiprocessing.Process,重写了run方法。if __name__ == "__main__"语句是为了在 Windows 系统中避免多进程创建时的递归问题。p.start()启动子进程,p.join()等待子进程执行完毕。

  • 8.1.2 进程池
    multiprocessing.Pool可以创建一个进程池,用于管理多个进程。通过控制进程池中的进程数量,可以方便地控制并发数量,提高资源利用率。示例代码如下
import multiprocessingdef task(x):return x * xif __name__ == "__main__":with multiprocessing.Pool(processes=4) as pool:results = pool.map(task, range(10))print(results)

在上述代码中,multiprocessing.Pool(processes=4)创建了一个包含 4 个进程的进程池。pool.map(task, range(10))task函数应用到range(10)的每个元素上,并行执行这些任务,并返回结果列表。

  • 8.1.3 ProcessPoolExecutor 并发编程
    concurrent.futures模块中的ProcessPoolExecutor提供了一种更简洁的多进程并发编程方式。通过submit()方法提交任务,result()方法获取任务结果。示例代码如下:
import concurrent.futuresdef task(x):return x * xif __name__ == "__main__":with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:future = executor.submit(task, 5)result = future.result()print(result)

在上述代码中,ProcessPoolExecutor(max_workers=4)创建了一个最大工作进程数为 4 的进程池。executor.submit(task, 5)提交任务,future.result()获取任务执行的结果。

  • 8.1.4 进程间的通信
    • multiprocessing.Queue(队列)multiprocessing.Queue用于在不同进程之间传递数据。一个进程可以使用put()方法将数据放入队列,另一个进程可以使用get()方法从队列中获取数据。示例代码如下:
import multiprocessingdef producer(queue):queue.put("数据1")queue.put("数据2")def consumer(queue):while not queue.empty():data = queue.get()print(f"消费数据: {data}")if __name__ == "__main__":queue = multiprocessing.Queue()p1 = multiprocessing.Process(target=producer, args=(queue,))p2 = multiprocessing.Process(target=consumer, args=(queue,))p1.start()p1.join()p2.start()p2.join()

 

  • multiprocessing.Pipe(管道)multiprocessing.Pipe创建一个管道,返回两个连接对象,分别用于在两个进程之间进行通信。示例代码如下:
import multiprocessingdef sender(conn):conn.send("你好,接收者!")conn.close()def receiver(conn):message = conn.recv()print(f"接收到的消息: {message}")conn.close()if __name__ == "__main__":parent_conn, child_conn = multiprocessing.Pipe()p1 = multiprocessing.Process(target=sender, args=(child_conn,))p2 = multiprocessing.Process(target=receiver, args=(parent_conn,))p1.start()p2.start()p1.join()p2.join()

8.2 多线程

  • 8.2.1 threading 模块
    threading.Thread类用于创建线程。与进程类似,通过重写run()方法来定义线程执行的任务。示例代码如下:
import threadingclass MyThread(threading.Thread):def run(self):print(f"线程 {self.name} 正在执行任务")if __name__ == "__main__":t = MyThread()t.start()t.join()print("主线程继续执行")

在上述代码中,MyThread类继承自threading.Thread,重写了run方法。t.start()启动线程,t.join()等待线程执行完毕。

  • 8.2.2 互斥锁 Lock
    当多个线程访问共享资源时,可能会导致资源竞争和数据不一致问题。threading.Lock互斥锁可以避免这些问题。通过acquire()方法获取锁,release()方法释放锁。示例代码如下:
import threadingcounter = 0
lock = threading.Lock()def increment():global counterlock.acquire()try:counter += 1finally:lock.release()threads = []
for _ in range(10):t = threading.Thread(target=increment)threads.append(t)t.start()for t in threads:t.join()print(f"计数器的值: {counter}")

在上述代码中,lock.acquire()获取锁,确保在修改counter时不会有其他线程同时访问。try-finally块保证无论是否发生异常,锁都会被正确释放。

  • 8.2.3 死锁
    死锁是指多个线程互相等待对方释放资源,导致所有线程都无法继续执行的情况。例如,线程 A 持有资源 1 并等待资源 2,线程 B 持有资源 2 并等待资源 1,就会发生死锁。预防死锁的方法包括:
    • 按照一定的顺序获取锁,避免交叉获取。
    • 设置锁的超时时间,避免无限等待。
    • 使用资源分配图算法检测和预防死锁。

8.3 线程通信

  • 8.3.1 使用 Condition 实现线程通信
    threading.Condition对象可用于线程间的条件变量通信。一个线程可以使用wait()方法等待特定条件满足,其他线程可以使用notify()notify_all()方法通知该条件已满足。示例代码如下:
import threadingcondition = threading.Condition()
shared_resource = 0def consumer():with condition:while shared_resource == 0:condition.wait()print(f"消费者消费了资源: {shared_resource}")shared_resource = 0def producer():with condition:global shared_resourceshared_resource = 10print(f"生产者生产了资源: {shared_resource}")condition.notify()t1 = threading.Thread(target=consumer)
t2 = threading.Thread(target=producer)t1.start()
t2.start()t1.join()
t2.join()

在上述代码中,消费者线程在资源为 0 时等待,生产者线程生产资源后通知消费者线程。

  • 8.3.2 使用 queue 实现线程通信
    queue模块提供了线程安全的队列,可用于线程之间传递数据,避免数据竞争。示例代码如下:
import queue
import threadingq = queue.Queue()def producer():q.put("数据1")q.put("数据2")def consumer():while not q.empty():data = q.get()print(f"消费数据: {data}")t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)t1.start()
t1.join()
t2.start()
t2.join()

 

  • 8.3.3 使用 Event 实现线程通信
    threading.Event对象可用于线程间的事件通知。一个线程可以使用set()方法设置事件,其他线程可以使用wait()方法等待事件触发。示例代码如下:
import threadingevent = threading.Event()def worker():print("工作线程等待事件...")event.wait()print("工作线程接收到事件,开始工作!")t = threading.Thread(target=worker)
t.start()input("按回车键设置事件...")
event.set()
t.join()

8.4 Thread - Local Data

threading.local类用于创建线程局部数据,每个线程都有自己独立的数据副本,互不干扰。常用于存储线程特定的上下文信息,例如每个线程的用户会话信息。示例代码如下:

import threadinglocal_data = threading.local()def worker():local_data.value = threading.current_thread().nameprint(f"{threading.current_thread().name} 的局部数据: {local_data.value}")threads = []
for i in range(3):t = threading.Thread(target=worker)threads.append(t)t.start()for t in threads:t.join()

在上述代码中,每个线程都可以独立地设置和访问local_data.value,不会相互影响。

8.5 ThreadPoolExecutor 并发编程

concurrent.futures模块中的ThreadPoolExecutor可用于多线程并发编程,方便管理线程池,提交和获取任务结果。示例代码如下:

import concurrent.futuresdef task(x):return x * xif __name__ == "__main__":with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:future = executor.submit(task, 5)result = future.result()print(result)

在上述代码中,ThreadPoolExecutor(max_workers=4)创建了一个最大工作线程数为 4 的线程池。executor.submit(task, 5)提交任务,future.result()获取任务执行的结果。

8.6 综合实例:多线程爬虫

利用多线程技术改进网络爬虫,可以同时发送多个请求,提高数据爬取效率。但需要注意处理线程安全问题,例如共享资源的访问控制。示例代码如下:

import requests
import threading
from bs4 import BeautifulSoupurls = ["https://example.com/page1", "https://example.com/page2", "https://example.com/page3"]
lock = threading.Lock()
results = []def crawl(url):response = requests.get(url)if response.status_code == 200:soup = BeautifulSoup(response.text, 'html.parser')# 这里可以根据具体需求提取数据data = soup.title.textwith lock:results.append(data)else:print(f"请求 {url} 失败,状态码: {response.status_code}")threads = []
for url in urls:t = threading.Thread(target=crawl, args=(url,))threads.append(t)t.start()for t in threads:t.join()print(results)

在上述代码中,多个线程同时爬取不同的网页,使用lock来保证在向results列表中添加数据时的线程安全。

8.7 安全专题

  • 8.7.1 暴力破解子域名
    通过多进程或多线程技术,可以对目标域名进行暴力破解子域名操作。使用字典文件尝试不同的子域名组合,例如:
import requests
import threadingtarget_domain = "example.com"
subdomains = []with open('subdomains.txt', 'r') as file:subdomains = file.read().splitlines()def check_subdomain(subdomain):url = f"http://{subdomain}.{target_domain}"try:response = requests.get(url)if response.status_code == 200:print(f"发现子域名: {url}")except:passthreads = []
for subdomain in subdomains:t = threading.Thread(target=check_subdomain, args=(subdomain,))threads.append(t)t.start()for t in threads:t.join()

在上述代码中,从字典文件中读取子域名列表,使用多线程尝试访问每个子域名,如果能获取到状态码为 200 的响应,则表示发现了一个有效的子域名。

  • 8.7.2 多文件的哈希计算
    同时对多个文件进行哈希计算(如 MD5、SHA - 256),利用多进程或多线程可以加速计算过程,确保文件完整性。以下是使用多线程计算文件 SHA - 256 哈希值的示例代码:
import hashlib
import threading
import osfiles = ["file1.txt", "file2.txt", "file3.txt"]
results = {}def calculate_hash(file_path):hash_obj = hashlib.sha256()with open(file_path, 'rb') as file:for chunk in iter(lambda: file.read(4096), b""):hash_obj.update(chunk)hash_value = hash_obj.hexdigest()with threading.Lock():results[file_path] = hash_valuethreads = []
for file in files:if os.path.isfile(file):t = threading.Thread(target=calculate_hash, args=(file,))threads.append(t)t.start()for t in threads:t.join()print(results)

在上述代码中,每个线程负责计算一个文件的哈希值,使用threading.Lock来保证在更新results字典时的线程安全。

  • 8.7.3 多进程生成哈希表
    使用多进程生成大规模的哈希表,可用于密码破解、数据比对等安全相关的场景。以下是一个简单的示例代码,展示如何使用多进程生成包含密码哈希值的哈希表:
import multiprocessing
import hashlibpasswords = ["password1", "password2", "password3"]
hash_table = {}def hash_password(password):hash_obj = hashlib.sha256()hash_obj.update(password.encode())hash_value = hash_obj.hexdigest()with multiprocessing.Lock():hash_table[password] = hash_valueif __name__ == "__main__":pool = multiprocessing.Pool(processes=multiprocessing.cpu_count())pool.map(hash_password, passwords)pool.close()pool.join()print(hash_table)

在上述代码中,使用multiprocessing.Pool创建进程池,每个进程负责计算一个密码的哈希值,并将其添加到hash_table中。multiprocessing.Lock用于保证在更新hash_table时的进程安全。

第 9 章 网络安全应用综合实践

9.1 密码学综合应用:文件安全传输

  • 9.1.1 实例具体要求
    文件安全传输的目标是保证文件的机密性(防止文件内容被窃取)、完整性(确保文件在传输过程中没有被篡改)和不可否认性(发送方不能否认发送过文件,接收方不能否认收到过文件)。为了实现这些目标,需要使用合适的加密算法、数字签名等技术。

  • 9.1.2 第三方库介绍
    cryptography库是一个强大的用于密码学的 Python 库,它提供了丰富的功能,包括对称加密、非对称加密、数字签名、哈希算法等。主要功能和使用方法如下:

    • 对称加密:可以使用cryptography.fernet模块进行对称加密,例如:
from cryptography.fernet import Fernet# 生成密钥
key = Fernet.generate_key()
cipher_suite = Fernet(key)# 加密数据
message = b"这是一段需要加密的消息"
encrypted_message = cipher_suite.encrypt(message)# 解密数据
decrypted_message = cipher_suite.decrypt(encrypted_message)
print(decrypted_message)
  • 非对称加密:使用cryptography.hazmat.primitives.asymmetric模块进行非对称加密,例如 RSA 算法:
    from cryptography.hazmat.primitives.asymmetric import rsa, padding
    from cryptography.hazmat.primitives import serialization, hashes# 生成私钥
    private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048
    )# 将私钥序列化为PEM格式的字符串
    private_pem = private_key.private_bytes(encoding=serialization.Encoding.PEM,format=serialization.PrivateFormat.PKCS8,encryption_algorithm=serialization.NoEncryption()
    )# 从PEM格式的字符串中加载私钥
    loaded_private_key = load_pem_private_key(private_pem,password=None
    )# 生成公钥
    public_key = private_key.public_key()# 将公钥序列化为PEM格式的字符串
    public_pem = public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo
    )# 从PEM格式的字符串中加载公钥
    loaded_public_key = load_pem_public_key(public_pem
    )# 要加密的数据
    message = b"这是一段需要加密的消息"# 使用公钥加密数据
    encrypted = loaded_public_key.encrypt(message,padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),algorithm=hashes.SHA256(),label=None)
    )# 使用私钥解密数据
    decrypted = loaded_private_key.decrypt(encrypted,padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),algorithm=hashes.SHA256(),label=None)
    )print(f"原始消息: {message.decode()}")
    print(f"加密后的消息: {encrypted.hex()}")
    print(f"解密后的消息: {decrypted.decode()}")
  • 9.1.3 具体编程实现
    下面是一个使用cryptography库实现文件加密、解密以及数字签名验证的示例。假设我们要实现发送方加密文件并对文件进行签名,接收方解密文件并验证签名的功能。
  • from cryptography.fernet import Fernet
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import padding, rsa
    from cryptography.hazmat.primitives.serialization import load_pem_public_key, load_pem_private_key# 生成对称加密密钥
    symmetric_key = Fernet.generate_key()
    cipher_suite = Fernet(symmetric_key)# 生成非对称加密的私钥和公钥
    private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048
    )
    public_key = private_key.public_key()# 发送方操作
    def sender_operation(input_file_path, output_encrypted_file_path, output_signature_file_path):# 读取文件内容with open(input_file_path, 'rb') as file:file_content = file.read()# 对称加密文件encrypted_file_content = cipher_suite.encrypt(file_content)# 对加密后的文件内容进行签名signature = private_key.sign(encrypted_file_content,padding.PSS(mgf=padding.MGF1(hashes.SHA256()),salt_length=padding.PSS.MAX_LENGTH),hashes.SHA256())# 保存加密后的文件和签名with open(output_encrypted_file_path, 'wb') as encrypted_file:encrypted_file.write(encrypted_file_content)with open(output_signature_file_path, 'wb') as signature_file:signature_file.write(signature)# 接收方操作
    def receiver_operation(input_encrypted_file_path, input_signature_file_path, output_decrypted_file_path):# 读取加密后的文件内容和签名with open(input_encrypted_file_path, 'rb') as encrypted_file:encrypted_file_content = encrypted_file.read()with open(input_signature_file_path, 'rb') as signature_file:signature = signature_file.read()try:# 验证签名public_key.verify(signature,encrypted_file_content,padding.PSS(mgf=padding.MGF1(hashes.SHA256()),salt_length=padding.PSS.MAX_LENGTH),hashes.SHA256())print("签名验证成功")except:print("签名验证失败")return# 对称解密文件decrypted_file_content = cipher_suite.decrypt(encrypted_file_content)# 保存解密后的文件with open(output_decrypted_file_path, 'wb') as decrypted_file:decrypted_file.write(decrypted_file_content)# 使用示例
    sender_operation('input.txt', 'encrypted.txt','signature.txt')
    receiver_operation('encrypted.txt','signature.txt', 'decrypted.txt')
    

     

  • 9.1.4 运行测试
    对上述编写的程序进行测试时,需要考虑多种情况。
    • 正常情况:确保文件在加密、传输和解密过程中没有数据丢失,签名验证能够成功通过。检查解密后的文件内容是否与原始文件内容一致。
    • 异常情况:
      • 修改加密后的文件内容,验证签名时应失败。
      • 使用错误的公钥进行签名验证,应无法通过验证。
      • 故意损坏签名文件,验证签名时也应失败。
      • 处理可能出现的异常,如文件不存在、权限不足等情况,确保程序不会崩溃,并且能够给出合理的错误提示信息。

9.2 计算机取证:元数据证据提取

  • 9.2.1 实例具体要求
    确定需要提取的元数据类型,常见的包括文件创建时间、修改时间、访问时间、作者信息、文件大小、文件格式等。目标数据源可以是硬盘、U 盘、移动硬盘等存储设备中的各种类型文件,如图片、文档(Word、PDF 等)、音频、视频等。

  • 9.2.2 第三方库介绍

  • exifread:用于提取图片的元数据。它可以读取图片中的 EXIF(Exchangeable Image File Format)信息,包括拍摄设备、拍摄时间、焦距、光圈等详细信息。使用示例如下:
    import exifreaddef extract_image_metadata(file_path):with open(file_path, 'rb') as f:tags = exifread.process_file(f)metadata = {}for tag, value in tags.items():if tag in ('EXIF DateTime', 'EXIF FocalLength', 'EXIF ApertureValue', 'Image Make', 'Image Model'):metadata[tag] = str(value)return metadata# 请将'your_image.jpg'替换为实际的图片路径
    image_path = 'your_image.jpg'
    image_metadata = extract_image_metadata(image_path)
    for tag, value in image_metadata.items():print(f"{tag}: {value}")

     

  • pdfminer.six:用于提取 PDF 文件的元数据。它可以提取 PDF 文件的标题、作者、创建时间、修改时间等信息,还可以提取文本内容。示例代码:
    from pdfminer.high_level import extract_text, extract_metadatadef extract_pdf_info(file_path):# 提取文本内容text = extract_text(file_path)# 提取元数据metadata = extract_metadata(file_path)pdf_info = {'title': metadata.get('Title', ''),'author': metadata.get('Author', ''),'creation_date': metadata.get('CreationDate', ''),'modification_date': metadata.get('ModDate', ''),'text': text}return pdf_info# 请将'your_pdf.pdf'替换为实际的PDF文件路径
    pdf_path = 'your_pdf.pdf'
    pdf_info = extract_pdf_info(pdf_path)
    for key, value in pdf_info.items():if key == 'text':print(f"{key}(部分内容展示):\n{value[:200]}...")else:print(f"{key}: {value}")
    

     

  • 9.2.3 具体编程实现
    下面是一个综合提取不同类型文件元数据的示例程序,支持图片和 PDF 文件。
    import exifread
    from pdfminer.pdfdocument import PDFDocument
    from pdfminer.pdfreader import PDFReader
    import osdef extract_metadata(file_path):file_extension = os.path.splitext(file_path)[1].lower()metadata = {}if file_extension == '.jpg':with open(file_path, 'rb') as file:tags = exifread.process_file(file)metadata['拍摄设备'] = str(tags.get('Image Make', '未知'))metadata['拍摄时间'] = str(tags.get('EXIF DateTimeOriginal', '未知'))elif file_extension == '.pdf':with open(file_path, 'rb') as file:reader = PDFReader(file)document = PDFDocument(reader)metadata['标题'] = document.info[0].title if document.info else '无标题'metadata['作者'] = document.info[0].author if document.info else '无作者信息'metadata['创建时间'] = document.info[0].creation_date if document.info else '未知'return metadata# 测试
    file_path = 'example.jpg'
    metadata = extract_metadata(file_path)
    print(metadata)file_path = 'example.pdf'
    metadata = extract_metadata(file_path)
    print(metadata)
    

     

  • 9.2.4 运行测试
    对程序进行准确性和稳定性测试:
    • 准确性:使用已知元数据的文件进行测试,检查提取的元数据是否与实际情况相符。对于不同格式、不同来源的文件,都要进行测试,确保能够正确提取各种类型的元数据。
    • 稳定性:测试程序在处理大量文件时的性能和稳定性,检查是否会出现内存泄漏、程序崩溃等问题。同时,处理文件不存在、文件损坏等异常情况时,程序应能够给出合理的错误提示,而不是崩溃。

9.3 异常检测:基于机器学习的异常检测

  • 9.3.1 实例具体要求
  • 定义异常检测的目标和场景,例如在网络流量监测中,检测异常的流量模式(如突然的流量激增、异常的请求频率等);在系统日志分析中,检测异常的事件(如频繁的登录失败、系统关键文件的异常修改等)。明确需要分析的数据来源,如网络流量日志、系统日志文件等。

  • 9.3.2 第三方库介绍
    scikit-learn是一个广泛使用的机器学习库,其中包含多种适合异常检测的算法:

    • Isolation Forest(孤立森林):通过构建孤立树来隔离样本,样本越孤立,其异常分数越高。适用于检测数据集中的孤立点或异常值。示例代码:
  • One-Class SVM(单类支持向量机):用于寻找一个最优超平面,将数据集中的正常样本与异常样本分开。适用于只有正常样本数据的情况,用于检测新数据中的异常。示例:
    from sklearn.svm import OneClassSVM
    import numpy as np# 生成示例数据
    data = np.array([[1], [2], [3], [4], [5]])# 创建One-Class SVM模型
    model = OneClassSVM(nu=0.1)# 拟合模型
    model.fit(data)# 预测异常
    new_data = np.array([[6], [0]])
    predictions = model.predict(new_data)
    print(predictions)
    

     

  • 9.3.3 具体编程实现
    以检测网络流量数据中的异常为例,假设我们有一个包含网络流量特征(如流量大小、请求频率等)的数据集。
    import numpy as np
    from sklearn.ensemble import IsolationForest
    from sklearn.model_selection import train_test_split# 生成一些示例网络流量数据(特征矩阵)
    np.random.seed(42)
    data = np.random.randn(100, 2)
    # 人为添加一些异常数据
    anomalies = np.array([[10, 10], [-10, -10]])
    data = np.concatenate((data, anomalies), axis=0)# 划分训练集和测试集
    X_train, X_test = train_test_split(data, test_size=0.2, random_state=42)# 创建孤立森林模型
    model = IsolationForest(contamination=0.05)# 拟合模型
    model.fit(X_train)# 预测测试集的异常
    predictions = model.predict(X_test)
    for i, prediction in enumerate(predictions):if prediction == -1:print(f"样本 {i} 被预测为异常")
    

    通过调整模型的参数(如IsolationForest中的contamination参数),优化模型性能,提高异常检测的效果。同时,可以使用交叉验证等方法来更准确地评估模型的泛化能力。

  • 9.3.4 运行测试
    评估模型的性能:
    • 准确率(Accuracy):计算预测正确的样本数占总样本数的比例。但在异常检测中,由于正负样本不均衡,准确率可能不是一个很好的评估指标。
    • 召回率(Recall):也称为查全率,计算正确预测为异常的样本数占实际异常样本数的比例。
    • 精确率(Precision):计算正确预测为异常的样本数占预测为异常的样本数的比例。
    • F1 值(F1-score):综合考虑精确率和召回率的指标,是精确率和召回率的调和平均数。

9.4 渗透测试:基本的 Web 渗透实践

  • 9.4.1 实例具体要求
    明确渗透测试的目标网站或 Web 应用,例如一个企业的官方网站、内部管理系统等。了解测试的范围,包括哪些页面、功能模块需要进行测试,以及哪些部分是禁止测试的。遵循相关法律法规和道德规范,确保渗透测试是在获得授权的情况下进行的,不得用于非法活动。

  • 9.4.2 环境配置
    搭建渗透测试环境:

    • 安装工具:安装必要的工具,如 Burp Suite(用于拦截、修改和分析 HTTP 请求和响应)、Nmap(用于网络扫描,发现目标主机的开放端口和服务)等。根据操作系统的不同,按照官方文档进行安装和配置。
    • 配置测试代理:如果需要使用代理工具(如 Burp Suite 的代理功能),需要在浏览器或其他工具中配置代理服务器的地址和端口,以便拦截和分析网络流量。
  • 9.4.3 相关工具和第三方库

    • requests:用于发送 HTTP 请求。在渗透测试中,可以使用它来模拟用户请求,发送各种类型的请求(GET、POST、PUT 等),并获取响应内容。示例代码:
      import requestsurl = 'https://example.com'
      response = requests.get(url)
      print(response.status_code)
      print(response.text)
      
  • BeautifulSoup:用于解析网页。在获取到网页的 HTML 内容后,可以使用BeautifulSoup提取其中的元素、链接、表单等信息,帮助进行信息收集和漏洞发现。示例:
    from bs4 import BeautifulSoup
    import requestsurl = 'https://example.com'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    links = soup.find_all('a')
    for link in links:print(link.get('href'))
    
  • 9.4.4 渗透步骤
    • 信息收集:使用 Nmap 等工具扫描目标主机的开放端口和服务,了解目标系统的基本架构。使用requestsBeautifulSoup等库爬取网站的页面内容,收集网站的目录结构、链接、表单等信息。还可以通过搜索引擎、Whois 查询等方式获取更多关于目标网站的信息。
    • 漏洞扫描:使用专门的漏洞扫描工具(如 Nessus、OpenVAS 等)或编写脚本,对目标网站进行漏洞扫描,检测常见的 Web 漏洞,如 SQL 注入、XSS(跨站脚本攻击)、文件上传漏洞等。
    • 漏洞利用:对于发现的漏洞,根据漏洞的类型和特点,使用相应的工具或编写代码进行漏洞利用,尝试获取系统权限或敏感信息。例如,对于 SQL 注入漏洞,可以构造恶意的 SQL 语句进行攻击。
    • 权限提升:如果成功获取了低权限的用户账户,尝试通过各种方法提升权限,例如利用系统漏洞、弱密码等,获取更高权限的账户,如管理员权限。
    • 数据获取:在获得足够的权限后,获取目标系统中的敏感数据,如用户信息、财务数据、业务数据等。
    • 后渗透:在渗透测试完成后,清理测试过程中留下的痕迹,如删除临时文件、关闭建立的连接等。对测试过程和发现的漏洞进行总结和报告,为目标系统的安全加固提供建议。

在进行渗透测试的过程中,要详细记录每一步的操作和发现,以便后续的分析和总结。同时,要始终遵守法律法规和道德规范,确保测试活动的合法性和安全性。

总结

通过对 Python 编程与网络安全知识的系统学习,全面掌握了从基础到高级的多个关键领域。

在 Python 编程方面,我们学习了函数和模块的使用,包括函数的定义、参数传递、高级特性等,以及模块化编程和打包工具的运用。同时,深入理解了面向对象程序设计的概念,如类和对象、继承、多态、定制类等,这些知识为编写结构清晰、可维护性强的代码奠定了坚实基础。多进程和多线程编程技术的学习,让我们能够充分利用计算机的多核资源,提高程序的执行效率,同时也了解了进程间和线程间的通信方式以及相关的安全问题。

在网络安全领域,我们从密码学的基础应用出发,学习了 MD5、凯撒密码、仿射密码等简单算法,以及 AES 等高级加密算法的原理和实现,掌握了文件安全传输的方法,确保文件的机密性、完整性和不可否认性。计算机取证方面,学会了提取不同类型文件的元数据作为证据,为调查和分析提供支持。基于机器学习的异常检测,利用scikit-learn库中的算法,能够有效地发现网络流量和系统日志中的异常行为。在渗透测试中,了解了基本的 Web 渗透步骤,以及相关工具和 Python 库的应用,提高了对 Web 应用安全的认识和防护能力。

然而,Python 编程和网络安全是不断发展和演进的领域,新的技术和挑战不断涌现。我们需要持续学习和实践,紧跟技术发展的步伐,不断提升自己的技能和知识水平。无论是在开发更安全的应用程序,还是在保护信息系统免受网络攻击方面,所学的知识都将发挥重要作用。通过不断探索和创新,我们能够更好地应对未来的网络安全挑战,为数字化世界的安全稳定贡献自己的力量。

喜欢就点点赞和评论关注一起进步呗

 

 

相关文章:

一文详细讲解Python(详细版一篇学会Python基础和网络安全)

引言 在当今数字化时代&#xff0c;Python 作为一种简洁高效且功能强大的编程语言&#xff0c;广泛应用于各个领域&#xff0c;从数据科学、人工智能到网络安全等&#xff0c;都能看到 Python 的身影。而网络安全作为保障信息系统和数据安全的关键领域&#xff0c;其重要性不言…...

使用QT调试LidarView

前段时间使用VeloView想进行点云的显示&#xff0c;后来发现VeloView的尺子测距不好用&#xff0c;也没有筛选点的功能&#xff0c;就放弃了。kitware同家的还有LidarView&#xff0c;功能多一些&#xff0c;更新的时间更晚&#xff0c;而且还兼容速腾、禾赛等多家点云设备可以…...

JAVA:使用 Curator 进行 ZooKeeper 操作的技术指南

1、简述 Apache Curator 是一个基于 ZooKeeper 的 Java 客户端库&#xff0c;它极大地简化了使用 ZooKeeper 的开发工作。Curator 提供了高层次的 API&#xff0c;封装了很多复杂的 ZooKeeper 操作&#xff0c;例如连接管理、分布式锁、Leader 选举等。 在分布式系统中&#…...

【SpringCloud】LoadBalance-负载均衡

4. 负载均衡-LoadBalance 4.1 为什么需要负载均衡&#xff1f; 不知道各位心中有没有女神&#xff0c;通常来说一个女神就会有多个舔狗&#xff0c;那这些舔狗呢&#xff0c;就会心甘情愿的帮女神干活&#xff0c;假设女神小美现在有三个舔狗&#xff0c;小美喜欢让这三个舔狗…...

[250401] OpenAI 向免费用户开放 GPT-4o 图像生成功能 | Neovim 0.11 新特性解读

目录 OpenAI 向免费用户开放 GPT-4o 图像生成功能Neovim 0.11 新特性解读更简化的 LSP 设置和配置内置自动补全改进的悬停文档诊断信息增强更多默认键映射终端模拟器改进其他改进 OpenAI 向免费用户开放 GPT-4o 图像生成功能 2025年4月1日早上&#xff0c;OpenAI CEO Sam Altm…...

VBA数据库解决方案第二十讲:SQL在VBA中几种常见的表达方式

《VBA数据库解决方案》教程&#xff08;版权10090845&#xff09;是我推出的第二套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;是学完字典后的另一个专题讲解。数据库是数据处理的利器&#xff0c;教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法…...

SAIL-RK3588J 核心板技术方案——高精度装配式建筑机器人控制‌

&#xff08;本方案契合《建筑机器人产业目录》政策要求&#xff09; 一、方案背景与政策支持‌ ‌政策驱动‌ 2025年2月《建筑机器人产业目录》明确将‌“高精度建筑机器人控制设备”‌纳入重点补贴范围&#xff0c;要求定位精度≤0.5mm、支持实时质检与多机协同&#xff0c…...

人工智能在生物医药领域的应用地图:AIBC2025将于6月在上海召开!

人工智能在生物医药领域的应用地图&#xff1a;AIBC2025将于6月在上海召开&#xff01; 近年来&#xff0c;人工智能在生物医药行业中的应用受到广泛关注。 2024年10月&#xff0c;2024诺贝尔化学奖被授予“计算蛋白质设计和蛋白质结构预测”&#xff0c;这为行业从业人员带来…...

C#高级:利用LINQ进行实体列表的集合运算

问题引入&#xff1a; Teacher实体的唯一标识符是Name和Classes字段&#xff08;或者说这两个字段唯一确定一条数据&#xff09;&#xff0c;如何对两个实体列表做交集、差集运算呢&#xff1f;&#xff08;并集直接调用AddRange方法即可&#xff09; 一、重写方法实现 1.原…...

Python项目-基于Flask的个人博客系统设计与实现(2)

源代码 续 {% extends base.html %}{% block title %}评论管理{% endblock %}{% block content %} <div class"container py-4"><div class"row"><div class"col-md-3"><div class"list-group mb-4"><a h…...

2023第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(真题题解)(C++/Java题解)

记录刷题的过程、感悟、题解。 希望能帮到&#xff0c;那些与我一同前行的&#xff0c;来自远方的朋友&#x1f609; 大纲&#xff1a; 1、日期统计-&#xff08;解析&#xff09;-暴力dfs&#xff08;&#x1f609;蓝桥专属 2、01串的熵-&#xff08;解析&#xff09;-不要chu…...

前端界面在线excel编辑器 。node编写post接口获取文件流,使用传参替换表格内容展示、前后端一把梭。

首先luckysheet插件是支持在线替换excel内容编辑得但是浏览器无法调用本地文件&#xff0c;如果只是展示&#xff0c;让后端返回文件得二进制文件流就可以了&#xff0c;直接使用luckysheet展示。 这里我们使用xlsx-populate得node简单应用来调用本地文件&#xff0c;自己写一个…...

‌在 Fedora 系统下备份远程 Windows SQL Server 数据库的完整方案

‌一、环境准备与工具安装‌ ‌1. 安装 Microsoft SQL Server 命令行工具‌ Fedora 需安装 mssql-tools 和 ODBC 驱动&#xff1a; # 添加 Microsoft 仓库 sudo curl -o /etc/yum.repos.d/msprod.repo https://packages.microsoft.com/config/rhel/8/prod.repo# 安装工具包 …...

从24GHz到71GHz:Sivers半导体的广泛频率范围5G毫米波产品解析

在5G技术的浪潮中&#xff0c;Sivers半导体推出了创新的毫米波无线产品&#xff0c;为通信行业带来高效、可靠的解决方案。这些产品支持从24GHz到71GHz的频率&#xff0c;覆盖许可与非许可频段&#xff0c;适应高速、低延迟的通信场景。 5G通信频段的一点事儿及Sivers毫米波射频…...

从【抖音安全与信任中心】观察企业如何做算法透明

抖音主动公开算法原理树立行业新标杆&#xff1a; “抖音安全与信任中心”网站&#xff08;95152.douyin.com&#xff09; 1 算法透明的几点准则 需涵盖技术逻辑公开、治理机制可查、用户参与共建等维度。以下是基于抖音案例总结的可行路径&#xff0c;以及几个准则&#xff1…...

html处理Base文件流

处理步骤 从服务返回的字符串中提取文件流数据&#xff0c;可能是Base64或二进制。将数据转换为Blob对象。创建对象URL。创建<a>元素&#xff0c;设置href和download属性。触发点击事件以下载文件。删除缓存数据 代码 // 假设这是从服务返回的Base64字符串&#xff08…...

MySQL内存管理机制详解

目录标题 MySQL内存管理机制详解1. **内存组成与核心组件**2. **RSS与共享内存的关系**3. **OOM问题排查步骤**4. **典型案例** Buffer Pool&#xff08;缓冲池&#xff09; 确实属于共享内存&#xff08;Shared Memory&#xff09;的核心组成部分&#xff1f;1. **Buffer Pool…...

《算法笔记》9.7小节——数据结构专题(2)->堆 问题 C: 合并果子(堆)

题目描述 在一个果园里&#xff0c;多多已经将所有的果子打了下来&#xff0c;而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并&#xff0c;多多可以把两堆果子合并到一起&#xff0c;消耗的体力等于两堆果子的重量之和。可以看出&#xff0c…...

化繁为简解决leetcode第1289题下降路径最小和II

1289.下降路径最小和II 难度&#xff1a;困难 问题描述&#xff1a; 给你一个nxn整数矩阵grid&#xff0c;请你返回非零偏移下降路径数字和的最小值。 非零偏移下降路径定义为&#xff1a;从grid数组中的每一行选择一个数字&#xff0c;且按顺序选出来的数字中&#xff0c;…...

蓝桥杯省模拟赛 数位和

问题描述 只能被 1 和本身整除的数称为质数。 请问在 1 &#xff08;含&#xff09;到 1000000 &#xff08;含&#xff09;中&#xff0c;有多少个质数的各个数位上的数字之和为 2323 。 提示&#xff1a;599 就是这样一个质数&#xff0c;各个数位上的数字之和为 59923 。…...

MySQL和Oracle批量插入SQL差异详解

文章目录 MySQL和Oracle批量插入SQL差异详解1. 基本批量插入语法1.1 MySQL批量插入1.2 Oracle批量插入 2. 带序列的批量插入2.1 MySQL带自增ID的批量插入2.2 Oracle带序列的批量插入 3. 条件批量插入3.1 MySQL条件批量插入3.2 Oracle条件批量插入 MySQL和Oracle批量插入SQL差异…...

YOLOv5配置训练以及华为昇腾910B推理

参考文章&#xff1a; 保姆式yolov5教程&#xff0c;训练你自己的数据集 - 知乎 Windows 10|11下安装mmyolo-0.5.0版本 - 知乎 Ubuntu22.04安装教程&基于华为Ascend AI处理器的om模型atc转换环境安装_ubuntu安装atc工具-CSDN博客嵌入式AI---在华为昇腾推理自己的yolov5目标…...

Visual Studio Code配置自动规范代码格式

目录 前言1. 插件安装2. 配置个性化设置2.1 在左下角点击设置按钮 &#xff0c;点击命令面板&#xff08;或者也可以之间按快捷键CtrlShiftP&#xff09;2.2 在弹出的搜索框输入 settings.json&#xff0c;打开首选项&#xff1a;打开工作区设置&#xff1b;2.3 在settings.jso…...

【网安面经合集】42 道高频 Web 安全面试题全解析(附原理+防御+思路)

对于正在准备 安全岗求职或实习的同学们来说&#xff0c;Web 安全面试题几乎是必问项。 尤其是一些经常出现的考点&#xff0c;比如 SQL 注入、XSS、CSRF、反序列化、逻辑漏洞、WAF 绕过等等&#xff0c;不仅需要你知道“是什么”&#xff0c;还得能“讲清楚原理、分类、修复和…...

论文笔记(七十五)Auto-Encoding Variational Bayes

Auto-Encoding Variational Bayes 文章概括摘要1 引言2 方法2.1 问题场景2.2 变分下界2.3 SGVB估计器与AEVB算法2.4 重参数化技巧 3 示例&#xff1a;变分自编码器&#xff08;Variational Auto-Encoder&#xff09;4 相关工作5 实验6 结论7 未来工作 文章概括 引用&#xff1…...

前端学习记录之HTML

1. 网页 1.1 什么是网页 网站是指在因特网上根据一定的规则&#xff0c;使用HTML等制作的用于展示特定内容相关的网页集合。 网页是网站中的一“页”&#xff0c;通常是HTML格式的文件&#xff0c;它要通过浏览器来阅读 网页是构成网站的基本元素。它通常由图片&#xff0c;…...

程序化广告行业(39/89):广告投放的数据分析与优化秘籍

程序化广告行业&#xff08;39/89&#xff09;&#xff1a;广告投放的数据分析与优化秘籍 在程序化广告的领域中&#xff0c;数据分析与优化调整是实现精准投放、提升广告效果的核心环节。作为一名热衷于探索程序化广告的学习者&#xff0c;我希望通过这篇博客&#xff0c;和大…...

蓝桥杯 01游戏

问题描述 小蓝最近玩上了 01 游戏&#xff0c;这是一款带有二进制思想的棋子游戏。 游戏在一个大小为 N N 的棋盘上进行。棋盘上的每个位置都需要放置一个数字 0 或 1。初始情况下&#xff0c;棋盘上有一部分位置已经放置了固定的数字&#xff0c;玩家不可以更改这些位置。其…...

NoSQL 数据库的适用场景与局限性分析

NoSQL(Not Only SQL)数据库是一类非关系型数据库,通过灵活的数据模型和分布式架构解决传统关系型数据库在扩展性、性能和数据多样性上的瓶颈。以下从技术特性、适用场景、不适用场景及行业实践展开分析: 一、NoSQL数据库的核心技术特性 四大数据模型 文档型:以JSON/BSON格…...

个人网站:基于html、css、js网页开发界面

1、注册 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>注册页面</title><link rel&qu…...

嵌入式图像采集与显示系统实战详解:基于V4L2与Framebuffer的实现

在嵌入式Linux开发中&#xff0c;图像采集与显示是非常典型的一类应用场景。本文将基于 ARM9&#xff08;S3C2410&#xff09; 平台&#xff0c;深入讲解如何使用 V4L2 框架从 USB 摄像头采集图像数据&#xff0c;并通过 Framebuffer 接口实时显示到 LCD 屏幕。内容涵盖驱动架构…...

庙算兵棋推演AI开发初探(6-神经网络开发)

碎碎念&#xff1a; 老师让我和同学组队参加10月底截止报名的庙算比赛&#xff0c;我俩走运进了64强&#xff0c;打的过程中发现了一个重要问题——为什么别人总能打我&#xff0c;但是我都看不见&#xff01;就像玩dota被对面英雄莫名其妙单杀了但是他就一直隐身我都不知道怎…...

嵌入式硬件篇---嘉立创PCB绘制

文章目录 前言一、PCB绘制简介1.1绘制步骤1.1.1前期准备1.1.2原理图设计1.1.3原理图转PCB1.1.4PCB布局1.1.5布线1.1.6布线优化和丝印1.1.7制版 1.2原理1.2.1电气连接原理1.2.2信号传输原理1.2.3电源和接地原理 1.3注意事项1.3.1元件封装1.3.2布局规则1.3.3过孔设计1.3.4DRC检查…...

AI与.NET技术实操系列(四):使用 Semantic Kernel 和 DeepSeek 构建AI应用

1. 引言 在人工智能技术飞速发展的今天&#xff0c;大型语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为智能应用开发的核心驱动力。从智能客服到自动化内容生成&#xff0c;LLMs的应用正在深刻改变我们的工作和生活方式。 对于.NET开发者而言&#xff0c;…...

Vue 组件 - Slot 内容分发

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue组件 - Slot 内容分发 目录 Slot内容分发 旧版slot 单插槽 使用插槽 具名插槽 插槽实现导航 使用插槽优点 新版slot Or 插槽版抽屉 总结 Slot内容分发 混合父组件的内容和子组件自己模板 -- 内容分发 父组件模…...

Mysql之事务(下)

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 5. 事务的隔离级别与并发控制 5.1事务的隔离级别 5.2查看与设置事务的…...

LabVIEW液压控制系统开发要点

液压控制系统开发需兼顾高实时性、强抗干扰性和安全性&#xff0c;尤其在重工业场景中&#xff0c;毫秒级响应延迟或数据异常都可能导致设备损坏。本文以某钢厂液压升降平台项目为例&#xff0c;从硬件选型、控制算法、安全机制三方面&#xff0c;详解LabVIEW开发中的关键问题与…...

mybatis-genertor(代码生成)源码及扩展笔记

文章目录 生成过程MyBatisGenerator.generate()代码入口 pid0,id0context.generateFiles()代码 pid0,id1introspectedTable.getGeneratedJavaFiles() java部分生成 pid1,id11introspectedTable.getGeneratedXmlFiles() xml部分生成 pid1,id12这里是一波三连调用XMLMapperGenera…...

Mysql-数据库、安装、登录

一. 数据库 1. 数据库&#xff1a;DataBase&#xff08;DB&#xff09;&#xff0c;是存储和管理数据的仓库。 2. 数据库管理系统&#xff1a;DataBase Management System&#xff08;DBMS&#xff09;,操纵管理数据库的大型软件 3. SQL&#xff1a;Structured Query Language&…...

HTTP 请求方法

HTTP 请求方法 引言 HTTP(超文本传输协议)是互联网上应用最为广泛的网络协议之一。它定义了客户端与服务器之间通信的规则。HTTP请求方法,也称为HTTP动词,是客户端向服务器发送请求时使用的操作类型。本文将详细介绍HTTP请求方法的概念、分类、常用方法及其在实际应用中的…...

群体智能优化算法-算术优化算法(Arithmetic Optimization Algorithm, AOA,含Matlab源代码)

摘要 算术优化算法&#xff08;Arithmetic Optimization Algorithm, AOA&#xff09;是一种新颖的群体智能优化算法&#xff0c;灵感来源于加、减、乘、除四种基本算术运算。在优化过程中&#xff0c;AOA 通过乘除操作实现全局探索&#xff0c;通过加减操作强化局部开发&#…...

4.1-python操作wrod/pdf 文件

1.读取word文件 首先安装软件包 pip3 install python-docx from docx import Documentimport os path os.path.join(os.getcwd(),你的文档名字.docx)# 加载文档 doc Document(path)# 遍历数据 for p in doc.paragraphs:print(p.text)# 遍历文档中所有表格 for t in doc.t…...

C# 窗体应用(.FET Framework) 线程操作方法

一、Thread线程使用方法 初始化方法 Thread th1; th1 new Thread(方法名); th1.IsBackground true; th1.Start();传参 ///定义一个object接受参数的方法 private void Test(object n){string str1 n as string; MessageBox.Show(str1); }// 调用方法 Thread th2 string s…...

vscode/cursor编辑器中vue3文件里面的css不能注释解决办法

升级了cursor后发现css或者html里面的代码不能单行注释了&#xff0c;真的很烦人&#xff0c;找了很多解决办法&#xff0c;还是定位到插件上&#xff0c;有一个vue的插件&#xff0c;把它禁用掉就可以注释了&#xff0c;然后再把这个插件启用&#xff0c;就可以使用了&#xf…...

Jenkins详细安装配置部署

Jenkins是一款流行的开源持续集成/持续交付(CI/CD)工具&#xff0c;可以实现自动化构建、测试和部署软件。下面是Jenkins的详细安装、配置和部署过程。 安装Jenkins 1. 安装Java Jenkins运行需要Java环境&#xff0c;因此需要先安装Java。具体安装方式根据不同的操作系统有所…...

《Linux运维总结:基于银河麒麟V10+ARM64架构CPU源码编译部署单实例redis7.2.6》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、环境信息 环境信息如下&#xff1a; 主机IP 操作系统 Redis版本 CPU架构 192.168.1.111 K…...

音视频开发---常用工具

一、VLC播放器 1. 简介 VLC多媒体播放器(最初命名为VideoLAN客户端)是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘、VCD影音光盘和各类流式协议。它也能作为unicast或multicast的流式服务器在IPv4或IPv6的高速连接下使用。 它融…...

Java 大视界 -- 基于 Java 的大数据分布式计算在基因测序数据分析中的性能优化(161)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

关于跨域与.NET的处理方案

在 Web 开发里&#xff0c;浏览器的同源策略是一项关键的安全机制。同源指的是两个 URL 的协议、域名和端口都相同。当浏览器从一个源&#xff08;域名、协议、端口&#xff09;的网页去请求另一个源的资源时&#xff0c;就会产生跨域问题。例如&#xff0c;从 http://www.exam…...

中级:Maven面试题精讲

一、引言 在Java开发中&#xff0c;Maven作为一款强大的项目管理和构建工具&#xff0c;被广泛应用于项目构建、依赖管理和插件机制等方面。面试官通过相关问题考察候选人对Maven核心功能的理解和实际应用能力&#xff0c;以及在复杂项目场景下合理配置和优化Maven的能力。本文…...