谷歌网络安全-VII-笔记-全-
谷歌网络安全 VII 笔记(全)
001:课程介绍

概述
在本节课中,我们将学习Python编程如何应用于常见的网络安全任务。课程将从Python基础开始,逐步构建知识体系,并通过安全相关的实例进行实践。
对网络安全专业人员的需求达到了前所未有的高度。
全球各地的组织都需要具备相关知识和技能的专业人员来保护其系统免受攻击者侵害。
随着威胁数量的上升,安全专业人员通常需要执行多样化的任务。
正因如此,我们将把另一个工具纳入我们的安全工具箱。
这个工具可以简化许多常见的安全任务。
这个工具不仅被安全专业人员使用,也被工程师和数据科学家广泛使用。
这个工具就是Python。
大家好。祝贺你在安全学习的道路上迈出了新的一步。
我叫Anhill,是谷歌的一名安全工程师。
很高兴能在这门课程中与大家同行。
如果你一直在按顺序学习,那么你已经应用过安全专业人员在检测、分析和响应过程中使用的特定工具。
你也学习了如何通过Linux和SQL与计算机进行通信。
现在,我们将重点学习如何使用Python编程来完成一些常见的安全任务。
当你考虑下一步职业发展时,你可能会发现Python技能将在你的日常工作中提供帮助。
本课程专为学习Python而设计,从基础知识开始。
然后,你将逐步在这些基础上进行构建,并将所学知识应用到与安全相关的实例中,以获得动手实践的机会。
幸运的是,Python以其可读性而闻名,并且像所有语言一样,通过练习会变得更容易。
很快,你可能就会在你的安全职业生涯中使用Python。
Python可以自动化重要任务(如文件解析)中的手动工作。
Python在我的谷歌职业生涯中给了我很大帮助。
我所在的团队负责保护谷歌的基础设施,这包括员工使用的所有设备,从笔记本电脑、台式机到网络和云资源。
我们通过设计安全解决方案和自动化工作中可重复的部分来实现这一目标。
我喜欢Python的一点是它具有跨平台支持,并且安全社区的成员已经开发了许多使用Python的工具。
这使我能够轻松找到所需的工具,并在遇到阻碍时获得支持,从而完成我的专业和个人项目。
我希望这门课程能对你有所帮助。
让我们来了解一下课程内容。
首先,你将学习Python的基本编程概念。
你将了解Python为何被全球的安全专业人员所采纳。
你还将开发并运行你的第一个程序。
之后,我们将专注于编写高效的Python代码。
我们将讨论有助于提高工作效率的概念。
我们的下一个主要主题是关于处理字符串和列表。
这些内容将与你将在安全环境中遇到的许多数据密切相关。
最后,你将以探索Python的实际应用来结束本课程。
你将学习如何打开和解析文件,以及如何调试代码。

总结
本节课中,我们一起了解了Python对于安全分析师而言是一项非常有用的技能,并预览了本课程的主要学习路径。让我们开始学习吧。
002:安吉尔的个人职业之旅 🚀

在本节课中,我们将跟随谷歌安全工程师安吉尔(Zanghi)的分享,了解他如何从童年好奇心成长为一名专业网络安全工程师的个人职业旅程。他的经历揭示了进入网络安全领域的关键动力、所需技能以及持续学习的重要性。
从好奇心到技术之路
我的名字是安吉尔,是谷歌的一名安全工程师。
我人生中的许多经历将我引向了安全领域。
其中之一无疑是我成长过程中的好奇心。
我的父母是会计师,所以他们有袖珍计算器、机械铅笔和钢笔。
我总是把它们拆开,取出零件,试图弄清楚它们的工作原理。
这让我对广义上的技术产生了兴趣。
同样的概念再次得到应用,即试图弄清楚事物如何运作并“破坏”它们。
这基本上就是安全领域试图做的事情:通过“破坏”事物来弄清楚是否有人能在你之前破坏它们。
职业起点与转型动机
我的职业生涯始于网络工程师。
这份工作是为不同的公司设置防火墙、交换机和路由器。
我想加入网络安全领域,主要是因为我被行业内发生的事情深深激励,例如“极光行动”——谷歌被外国行为者黑客攻击的事件。
当时我阅读相关报道,并心想,我希望能与那些在前线处理这些问题的人们一起工作。
主动学习与技能提升
当我开始进入网络安全领域,并希望实现职业跳跃时,我明确了我想学习什么以及我需要达到什么水平。
一个例子是通过Python学习自动化。
我参加了在线课程。
我完成了认证,特别是非常流行的安全认证。
然后,我开始将其中一些方面融入到我当时的工作中。
适应变化与持续学习
当我从墨西哥搬到美国工作时,我不得不学会如何保持灵活。
你必须学习新事物才能推动职业发展。
有时,你甚至需要学习新事物,只是为了保持在原地。
在安全领域,我认为在整个技术行业都是如此,但尤其是在网络安全领域,你必须不断地重塑自我,持续学习事物如何运作,以及你如何能帮助这个行业。
关键技能:韧性
在我的一生以及作为网络安全专业人士的职业生涯中,一项重要的技能是韧性。
当我第一次搬到美国时,我对韧性有了深刻的理解。
事情的发展并未如我所愿。
我必须不断尝试新事物。
并抱最好的希望。
这与我们作为安全专业人士的日常工作并无不同。

我们每天都在做这样的事情。
我们必须找到让事情运转的方法。
我们必须找到让项目按我们需要的方式运行的方法。
或者我们必须找到解决问题的方法。
行业需要多元化人才
网络安全领域需要更多具有不同背景的专业人士。
这意味着不同的经验、看待事物的不同方式、以及处理和解决问题的不同方法。
我们这个行业需要更多像你一样的人。
本节课总结
本节课中,我们一起学习了安全工程师安吉尔的职业旅程。他从童年拆解物品的好奇心出发,经历了网络工程师的起点,因行业事件激励而转型网络安全,并通过主动学习Python自动化等技能成功转型。他的经历强调了在快速变化的技术领域,保持好奇心、主动学习新技能(如 Python 自动化)、培养韧性以及拥抱多元化背景对于网络安全职业发展的重要性。他的故事鼓励所有初学者,不同的视角和经验正是这个行业所急需的。
003:欢迎来到第一周


在本节课中,我们将开始学习Python编程语言的基础知识。我们将了解编程的基本概念、Python的数据类型、变量以及如何编写条件语句和循环语句。这些是构建自动化脚本以执行网络安全任务的核心基石。
学习一门新的编程语言类似于学习一门新的人类语言。编程语言由单词组成。这些单词被组织在一起,形成代码行。代码行用于与计算机通信,类似于句子。代码行告诉计算机如何执行一项任务。
在本节中,我们将开始学习与计算机通信所需的语言,同时探索Python的一些关键组成部分。
为什么学习Python
我们将从介绍编程的基础知识开始,首先探讨为什么安全分析师会使用Python。
学习Python帮助我在职业生涯中取得成功,因为使用Python使我能够从重复性任务中解放时间,转而专注于更具挑战性的任务和问题。成功应用自动化可以减少我的整体工作量,提高生产力,并降低人为错误的风险。自动化的使用也使我能够专注于需要更多创造力、协作和解决问题的工程任务。
Python编程基础
接下来,我们将开始构建Python的基础。我们将讨论数据类型,然后介绍变量。最后,我们将学习可以在Python中编写的特定语句,例如条件语句。
以下是Python中的基本数据类型:
- 字符串:用于表示文本,例如
"Hello, World!"。 - 整数:用于表示没有小数部分的数字,例如
42。 - 浮点数:用于表示有小数部分的数字,例如
3.14。 - 布尔值:用于表示逻辑真或假,即
True或False。
变量是用于存储数据的容器。你可以这样给变量赋值:
username = "admin"
login_attempts = 3
is_logged_in = False

控制程序流程的语句
条件语句帮助我们为程序加入逻辑。它们允许程序根据特定条件做出决策。
我们将要学习的第二种语句是迭代语句。迭代语句允许我们多次重复一行代码,而无需重写它。例如,for 循环可以遍历一个列表:
for ip in suspicious_ips:
print(f"Checking IP: {ip}")
你准备好开始用Python编程了吗?让我们开始吧。

总结

本节课中,我们一起学习了Python编程的入门知识。我们了解了学习Python对网络安全工作的重要性,它能够通过自动化提升效率和准确性。我们初步认识了编程的基本元素,如数据类型、变量,并简单接触了控制程序流程的条件语句和循环语句。这些概念是后续编写自动化脚本的基础。
004:Python与网络安全


在本节课中,我们将要学习编程在网络安全领域的应用,特别是Python语言如何帮助安全专业人员自动化日常任务,从而提高工作效率和准确性。
什么是编程?🤔
上一节我们介绍了安全专业人员使用的各种工具。本节中我们来看看其中一种核心工具:计算机编程。
编程是为计算机创建一套特定指令以执行任务的过程。我们可以通过一个自动售货机的例子来理解它。
将自动售货机想象成一台为顾客提供食物或饮料的计算机。为了获得商品,顾客需要向机器投入钱币,然后选择他们想要的商品。
假设顾客向机器提供了5美元。机器会存储这个数值,同时顾客进行选择。如果顾客选择了一个价值2美元的糖果棒,机器会接收这个输入(也称为指令),然后理解并输出价值2美元的糖果棒,并找回3美元零钱。
为什么选择Python?🐍
世界上存在许多编程语言。这里我们将重点介绍Python。
Python被认为是一种通用语言。这意味着它可以创建各种不同的程序,并且不专门针对任何特定问题。在Web开发和人工智能等领域,Python通常用于构建网站和进行数据分析。
在安全领域,我们使用Python的主要原因是自动化我们的任务。
自动化是指利用技术来减少执行常见和重复任务所需的人工和手动劳动。Python通常最适合自动化简短、简单的任务。
以下是Python在安全领域的一些应用示例:
- 日志分析:处理安全事件的分析师可能有一个包含必要信息的日志。手动阅读这些信息会花费太多时间,但Python可以帮助筛选,让分析师快速找到所需内容。
- 访问控制列表管理:分析师可以使用Python来管理访问控制列表(即控制谁可以访问系统及其资源的列表)。如果每次有员工离职,分析师都必须手动移除其访问权限,这可能会降低一致性。然而,一个Python程序可以定期监控并自动执行此操作。
- 网络流量分析:Python也可以执行一些自动化任务,如分析网络流量。虽然这些任务可以通过外部应用程序完成,但使用Python同样可以实现。
Python的优势 ✨
除了自动化单个任务,Python还可以将单独的任务组合成一个工作流。例如,想象一个操作手册指示分析师需要通过删除文件然后通知相关人员来解决某种情况。Python可以将这些流程连接在一起。
那么,安全专业人员究竟为何选择Python来完成这些任务呢?Python作为一种编程语言具有以下几个优势:
以下是Python的主要优势:
- 用户友好:Python类似于人类语言,需要的代码更少,且易于阅读。
- 代码规范:Python程序员遵循标准指南(如PEP 8),这确保了代码设计和可读性的一致性。
- 丰富的社区支持:学习Python的另一个重要原因是拥有大量的在线支持社区和资源。
- 强大的标准库和第三方库:Python拥有一个广泛的基础代码库(标准库)和第三方库,我们可以导入并使用它们来执行许多不同的任务。
这些只是Python在全球不同行业中持续保持高需求的部分原因。在你的安全职业生涯中,你很可能会用到它。


本节中我们一起学习了编程的基本概念,了解了Python语言在网络安全自动化任务中的核心作用及其主要优势。接下来,我们将短暂休息,然后在下一个视频中正式开始运行一些Python代码。
005:创建一个基本的Python脚本 🐍

在本节课中,我们将学习如何编写并运行一个基础的Python脚本。我们将从理解脚本与程序的区别开始,然后动手创建一个包含注释和打印功能的简单脚本,并最终运行它。
上一节我们介绍了Python的基础知识。本节中,我们将练习编写和运行代码。
在Python中,我们编写的代码被称为脚本或程序。两者之间存在细微差别。我们可以将计算机程序比作一场戏剧表演。
几乎每场戏剧表演都有一份书面剧本。演员们学习和记忆剧本,以便向观众念出台词。然而,这并非表演的全部。整个表演还包括导演对灯光、服装和舞台布景等做出的决策。整个表演涉及许多设计选择,如场景设计、灯光和服装。
创建这个作品的过程类似于Python编程的过程。编程涉及许多设计决策。但在Python中编写脚本的过程,更像是撰写演员将要念出的具体台词。
在Python中,良好的实践是从一个注释开始。注释是程序员为说明代码意图所做的笔记。现在让我们添加一个。
我们以井号 # 开始,表明这是一行注释,然后添加关于我们意图的细节。在这里,我们打算在屏幕上打印“hello Python”。
# 在屏幕上打印“hello Python”
现在,让我们编写第一行Python代码。这段代码使用 print 函数。print 函数将指定的对象输出到屏幕。在 print 之后,我们将要输出的内容放在括号内。在本例中,我们想输出字符串“hello Python”。我们必须将字符串数据放在引号中。
print("hello Python")
这些引号只是你在Python中会遇到的一种语法示例。语法指的是决定计算语言中正确结构的规则。
现在,我们将运行这段代码,以便计算机能够输出这个字符串。
运行代码后,由于我们的语法正确,字符串现在被显示出来。你刚刚运行了你的第一行代码。


现在你已经体验了在Python中编写和运行代码,我们已准备好讨论其基本组件。下节课见。
006:Python与网络安全专业人员 👨💻

概述
在本节课程中,我们将跟随谷歌安全工程师阿卡什的分享,了解Python编程语言在网络安全领域的核心价值与应用场景。我们将探讨为什么Python是网络安全专业人员的必备技能,以及如何开始学习并利用它来应对实际工作中的挑战。
我叫阿卡什,是谷歌的一名安全工程师。作为一名网络安全工程师,在你的职业生涯中,大部分时间都会用到Python。
当你进入网络安全领域时,学习Python非常重要。你将处理数以百万计的数据点,手动处理这些数据会非常困难。这时,Python就能发挥作用,通过自动化和编写脚本或小程序,在瞬间完成同样的工作。
当你看到大约10行代码就能在几秒钟内处理数兆字节的数据时,学习Python会变得非常有趣且充满成就感。
Python拥有丰富的学习资源和活跃的开源社区,社区成员也非常乐于助人。保持好奇心,尝试解决一些小问题,并亲自动手实践。不要害怕查阅语法,要善于利用在线资源进行学习。
上一节我们了解了Python在网络安全中的重要性,接下来我们看看阿卡什在谷歌的具体工作内容。
作为谷歌Chrome团队的安全工程师,我的工作是保护我们的客户免受外国政府以及世界各地持续威胁的攻击。

威胁是无限的,没有边界,这也正是网络安全领域令人兴奋的地方。
因此,请坚持下去。Python是一项必备技能,初期可能需要一些时间来掌握,但它将在你的整个职业生涯中持续发挥作用。

总结
本节课中,我们一起学习了网络安全工程师阿卡什的观点。我们了解到,Python是处理海量安全数据、实现任务自动化的关键工具,能极大提升工作效率。学习Python的过程充满乐趣和成就感,并且有丰富的社区资源支持。面对无限的网络安全威胁,掌握Python这项核心技能,对于构建长久的职业生涯至关重要。
007:Python中的数据类型


概述
在本节中,我们将学习Python中一个核心概念:数据类型。理解数据类型是编写有效代码的基础,它决定了数据如何被存储、操作和解释。我们将介绍五种主要的数据类型:字符串、整数、浮点数、布尔值和列表。
数据类型简介
首先,让我们通过一个生活中的例子来理解分类的概念。在厨房烹饪时,我们会将食材分类,例如胡萝卜和辣椒属于蔬菜,鸡肉和牛肉属于肉类。这些分类很重要,因为它们决定了我们处理这些食材的方式。
在Python中,数据类型也起着类似的作用。数据类型是特定类型数据项的一个类别。Python使用多种数据类型,本节我们将重点介绍字符串、浮点数、整数、布尔值和列表。
字符串(String)
当我们之前打印文本“Hello, Python”时,这就是一个字符串的例子。字符串数据是由有序字符序列组成的数据。这些字符可以是字母、符号、空格,甚至是数字。但需要注意的是,字符串类型中的数字不能用于数学计算。
字符串中的所有字符必须放在引号内。幸运的是,如果你忘记加引号,Python会通过给出错误信息来提醒你。
让我们用之前的代码来探索一下,当我们漏掉引号时会发生什么。
print(Hello, Python)
注意,我们在字符串末尾缺少了一个引号。当我们运行这段代码时,会收到一个错误信息。
数值类型:浮点数与整数
Python也支持数值数据类型。处理数值数据时,我们不需要在数据周围加引号。数值数据包括浮点数和整数。
浮点数是包含小数点的数字数据。这包括像2.1或10.5这样的分数,也包括带有小数点的整数,如2.0或10.0。
整数是不包含小数点的数字数据。像0、-9和5000这样的数字都是有效的整数。
到目前为止,我们使用print函数来输出字符串。但它也可以与浮点数和整数类型一起使用来进行计算。
让我们尝试一个例子。首先,按照良好实践,我们添加一个注释来解释代码的目的。
# 计算 1 + 1 的结果
print(1 + 1)
输出结果给出了答案:1加1等于2。我们可以使用print函数配合浮点数和整数数据来执行各种数学运算,如加法、减法、乘法和除法。
布尔值(Boolean)
Python中的第三种数据类型是布尔值。布尔数据只能是两个值之一:True(真)或False(假)。布尔值在我们的程序中对于逻辑判断非常有用。
例如,让我们比较数字并确定这些比较的布尔值。
# 比较数字
print(10 < 5)
print(9 < 12)
那么你认为结果是什么?10不小于5,但9小于12,对吧?让我们看看Python运行后的处理结果。
输出结果的第一行告诉我们,“10小于5”这个说法是False(假)。第二行告诉我们,“9小于12”这个说法是True(真)。当我们开始在代码中加入条件判断时,会更多地使用布尔值。
列表(List)
我们将要介绍的最后一个数据类型是列表。列表数据是一种数据结构,由按顺序排列的数据集合组成。
我们将创建并打印一个列表,其中包含有权访问某个机密文件的三位用户的用户名。
# 打印有权访问文件的用户列表
print(["user1", "user2", "user3"])
首先,我们添加关于打印此列表意图的注释。在关键字print之后,我们添加列表。我们需要将列表放在方括号[]内。之后,我们将列表中的各个项目放在引号中,并用逗号分隔它们。

运行这段代码,正如预期,我们得到了列表。打印时,它仍然带有方括号。这只是列表功能的开始。随着Python技能的增长,你将学习如何访问和编辑列表中的单个项目。
总结
本节课中,我们一起学习了Python中五种主要的数据类型:字符串、整数、浮点数、布尔值和列表。这些数据类型是我们后续课程中会经常用到的一些更常见的类型。理解它们将帮助你更好地组织和操作程序中的数据。

008:在Python中使用变量 🐍

概述
在本节课中,我们将要学习Python编程中的一个核心概念:变量。我们将了解变量是什么、如何创建和使用它们、它们与数据类型的关联,以及如何避免常见的错误。掌握变量是编写高效、清晰代码的基础。
变量:数据的容器 📦
上一节我们介绍了不同的数据类型,就像烹饪时对食材的分类。现在,我们来做另一个比较。在厨房里,我们还会使用存储容器。这些容器可以存放许多不同的东西。一顿饭后,一个容器可能装着米饭;另一顿饭后,它可能装着不同的东西,比如意大利面。
类似地,在Python中,我们有变量。一个变量是一个存储数据的容器。
创建变量
要创建一个变量,你需要为它起一个名字,然后添加一个等号,再指定要存储在其中的对象。
创建变量通常被称为赋值。命名变量的最佳实践是让名字与其用途相关。
让我们用一个变量来存储一个设备ID。我们将变量命名为 device_id,使用等号 =,然后给它赋值 "h32rb17"。因为这个变量的数据类型是字符串,所以我们将该值放在引号中。
device_id = "h32rb17"
运行这行代码后,我们的变量就保存在Python中了。
使用(调用)变量
创建变量的目的是为了在后续代码中使用它们。使用变量也可以被称为调用它们。要调用一个变量,只需输入它的名字。这会告诉Python使用该变量包含的对象。
让我们在刚刚写的代码基础上添加一行,来调用这个变量。我们将让它打印出这个变量。为此,我们使用 print 函数,并让它打印存储在 device_id 变量中的值。
print(device_id)
在 print 函数中使用变量时,我们不使用引号。这次运行后,Python会在屏幕上打印出 h32rb17。
变量 vs. 直接字符串
我们再添加一行代码来演示打印变量和打印字符串之间的区别。我们将要求Python打印一个包含另一个设备ID的字符串:"m50pi31"。因为这是字符串数据而不是变量,所以我们把它放在引号里。
print("m50pi31")
现在运行代码并查看结果。它执行了两个打印语句。第一个读取变量并打印其包含的值 h32rb17。第二个读取指定的字符串并打印 m50pi31。
既然可以直接使用这个字符串,为什么还需要变量呢?我们经常使用变量来简化代码,使其更清晰、更易读。或者,如果我们需要一个非常长的字符串或数字,将其存储在变量中可以让我们在整个代码中使用它,而无需全部打出来。
变量的数据类型
在上一个例子中,变量存储的是字符串数据。但变量可以存储各种数据类型。变量具有其当前存储对象的数据类型。
如果你不确定变量内部存储的数据类型,可以使用 type 函数。type 函数是一个返回其输入数据类型的函数。
让我们在Python中使用 type 函数。我们首先创建变量,然后添加一行包含 type 函数的代码。这行代码要求Python告诉我们 device_id 变量的数据类型,并将结果赋值给一个名为 data_type 的新变量。之后,我们可以将 data_type 变量打印到屏幕上。
device_id = "h32rb17"
data_type = type(device_id)
print(data_type)
完美!Python告诉我们 device_id 包含的值是一个字符串(<class 'str'>)。
类型错误
使用变量时,跟踪其数据类型非常重要。如果不这样做,可能会遇到类型错误。类型错误是由于使用了错误的数据类型而导致的错误。
例如,如果你尝试将一个数字和一个字符串相加,就会得到类型错误,因为Python无法将这两种数据类型组合在一起。它只能将两个字符串相加,或者将两个数字相加。
让我们演示一个类型错误。首先,我们使用存储字符串值的 device_id 变量。然后,我们定义另一个名为 number 的变量,并为其分配一个整数值。接着,我们编写一个打印语句,输出这两个变量的和。
device_id = "h32rb17"
number = 5
print(device_id + number)
运行这段代码,我们最终会得到一个错误,因为我们不能将字符串与数字相加。
重新赋值变量
关于变量,我们再讨论一个相关主题。之前我们提到变量就像容器,它们容纳的内容可以改变。定义变量后,我们随时可以更改其中的对象。这被称为重新赋值。
重新赋值变量与首次赋值非常相似。让我们尝试重新赋值一个变量。我们首先将相同的字符串 "h32rb17" 赋值给变量 device_id,并包含一行代码来打印这个变量。现在,让我们尝试重新赋值这个变量。我们输入变量名、一个等号,然后添加新对象。在本例中,我们将使用字符串 "n73abc07" 作为新的设备ID。我们还会要求Python再次打印该变量。
device_id = "h32rb17"
print(device_id)
device_id = "n73abc07"
print(device_id)

让我们看看运行后会发生什么。Python打印了两行输出。第一个打印语句发生在重新赋值之前,所以它首先打印字符串 h32rb17。但第二个打印语句发生在它改变之后,这就是为什么屏幕上第二个输出是字符串 n73abc07。
通过这段代码,我们将一个具有字符串值的变量重新赋值为另一个字符串值。但也可以将变量重新赋值为另一种数据类型的值。例如,我们可以将一个具有字符串值的变量重新赋值为一个整数值。
总结
本节课中,我们一起学习了Python中的变量。我们了解到变量是存储数据的容器,通过赋值来创建,通过名称来调用。变量可以存储任何数据类型,并且其数据类型由当前存储的内容决定。我们还学习了如何使用 type 函数检查数据类型,以及不匹配数据类型可能导致类型错误。最后,我们看到了变量可以被重新赋值,其内容可以在程序执行过程中改变。变量是Python的重要组成部分,随着课程的深入,你会对它们更加熟悉。
009:Python中的条件语句 🐍

在本节课中,我们将要学习Python编程中一个至关重要的概念——条件语句。它是实现自动化逻辑的基础,能让你的代码根据不同的情况做出不同的决策。
概述
之前,我们讨论了如何在变量中存储不同的数据类型。现在,我们将开始进入自动化的概念,以便用代码创建更智能的操作。
自动化是利用技术来减少执行常见和重复性任务所需的人工和手动劳动。它允许计算机为我们完成这些任务,从而让我们在生活中腾出更多时间去做其他活动。
条件语句对于自动化至关重要。一个条件语句,是一段评估代码以确定其是否满足指定条件的语句。
条件语句的核心:if 关键字
if 关键字在条件语句中非常重要。它用于开始一个条件语句。在这个关键字之后,我们指定必须满足的条件,以及如果条件满足将会发生什么。
我们每天都在使用 if 语句。例如:如果外面很冷,那么我们就穿外套。或者如果下雨,那么我们就带伞。
if 语句的结构包含我们想要评估的条件,以及如果条件满足时Python将执行的操作。Python总是评估条件是真还是假。如果为真,它就执行特定的操作。
让我们探索一个例子。
第一个 if 语句示例
我们将指示Python在登录失败尝试次数大于5时,打印一条“账户已锁定”的消息。
if failed_attempts > 5:
print("Account locked")
if关键字告诉Python开始一个条件语句。- 之后,我们指明要检查的条件。在这个例子中,我们检查用户的失败登录尝试是否超过5次。注意我们使用了一个名为
failed_attempts的变量。在完整的代码中,我们会在if语句之前为这个变量赋值。 - 在条件之后,我们总是放置一个冒号
:。这表示冒号后面的内容是我们希望在条件满足时发生的事情。 - 在这个例子中,当用户失败登录尝试超过5次时,它会打印“账户已锁定”的消息。
- 在Python中,这行消息必须至少缩进一个空格,以确保它只在条件为真时执行。
通常,我们将第一行称为头部,而将条件满足时执行的操作称为主体。
比较运算符
上面的条件是基于一个变量大于一个特定数字。但我们也可以使用各种运算符来定义条件。
以下是常用的比较运算符:
- 小于:
< - 大于:
> - 小于或等于:
<= - 大于或等于:
>= - 等于:
== - 不等于:
!=
特别注意:等于运算符 ==
当我们在条件语句中检查两个值是否相等时,需要使用特殊的语法:双等号 ==。
双等号是一个重要的运算符,常用于条件语句中。== 用于评估两个对象是否匹配。当它们匹配时,结果为布尔值 True;不匹配时,结果为 False。
不等于运算符 !=
感叹号后跟等号 != 表示“不等于”的条件。这个运算符评估两个对象是否不同。当它们不匹配时,结果为 True;匹配时,结果为 False。
使用 == 的示例
让我们更仔细地研究一个使用双等号的例子。我们将关注一个在特定操作系统运行时打印“需要更新”消息的示例。
if operating_system == "OS2":
print("Updates needed")
这里,我们创建了一个条件,用于检查设备的操作系统是否与标识该操作系统的特定字符串匹配。为此,我们需要在条件中使用双等号。当匹配时,我们的程序将打印“需要更新”的消息。
operating_system变量在双等号的左边。- 字符串
"OS2"在双等号的右边。 - 如果条件评估为
True,它将执行下一行缩进的代码中的操作。 - 在这里,如果操作系统是
OS2,它将打印“需要更新”。如果为False,则不会打印该消息。
注意这行代码是如何缩进的。这告诉Python该任务依赖于 if 语句评估为真。
现在,让我们编写包含此条件的代码并查看结果。
# 首先,为操作系统变量赋值
operating_system = "OS2"
# 然后,编写条件语句
if operating_system == "OS2":
print("Updates needed")
由于我们将 operating_system 变量设置为 "OS2",print 语句将会执行。运行这段代码,正如预期的那样,它打印了“Updates needed”,因为分配给 operating_system 变量的值等于 "OS2"。
引入 else 关键字
有时,我们希望条件语句在我们的第一个条件不成立时,执行另一组指令。在我们的例子中,“不成立”意味着设备运行的操作系统不是 OS2。这时,我们需要将 else 关键字纳入我们的条件语句中。
else 引导一段代码,该段代码仅当条件语句中所有前面的条件都评估为 False 时才执行。else 语句总是跟在 if 语句后面,并以冒号 : 结尾。
让我们使用之前的条件语句,并为其添加一个 else 语句。
# 这次,变量值不同
operating_system = "OS3"
if operating_system == "OS2":
print("Updates needed")
else:
print("No updates needed")
我们包含了相同的 if 语句。但这次,我们将 operating_system 变量设置为包含一个不同的操作系统 "OS3"。因为这不符合 if 语句条件中的值,所以“需要更新”的消息不会打印。但我们可以添加一个 else 语句,告诉它做其他事情。
我们输入 else 关键字,后跟冒号 :。然后缩进下一行,告诉它打印“无需更新”的消息。
当我们运行这段代码时,它会在 if 语句之后处理 else 语句。由于我们的 if 语句将评估为 False,它会继续执行 else 指令。运行代码,正如预期,它只打印了消息“No updates needed”。
总结
在本节课中,我们一起学习了Python中条件语句的基础知识。

- 我们了解了自动化的概念以及条件语句在其中的作用。
- 我们学习了如何使用
if关键字来创建条件分支,让代码根据条件(True或False)执行不同的操作。 - 我们认识了各种比较运算符,特别是用于判断相等的
==和用于判断不相等的!=。 - 最后,我们引入了
else关键字,它允许我们在if条件不满足时,提供一个备选的执行路径。
掌握 if 和 else 的使用,使你能够在代码中融入逻辑判断,这是编写智能、自动化程序的关键第一步。
010:使用for循环 🔄

概述
在本节课中,我们将要学习如何使用迭代语句,特别是for循环,来让计算机自动执行重复性任务。我们将了解for循环的语法结构、组成部分,以及如何结合range函数来精确控制循环次数。
上一节我们介绍了条件语句,它能让计算机做出决策。但有时,我们需要程序简单地计数或一遍又一遍地执行某个任务。
对于人类而言,处理繁琐的任务时容易分心和疲劳。在这种情况下,计算机就显得特别有用。本节中,我们将探讨计算机如何使用迭代语句来执行重复性任务。
迭代语句,也称为循环,是一段能重复执行一组指令的代码。设置循环可以让我们重复使用一行代码,而无需多次键入。
在讨论具体语法之前,我们先运行一个循环,让你感受一下它的效果。
for i in [1, 2, 3, 4]:
print(i)
请注意,这段代码仅用一条print语句就打印出了列表中的所有数字。这就是循环的作用。
我们将探讨两种类型的循环:for循环和while循环。我们刚刚运行的就是一个for循环,本节我们将继续重点介绍它。稍后,我们会再探讨while循环。
for循环会为指定的序列重复执行代码。一个典型的例子就是使用for循环来打印列表中的每一项。
for循环的结构
for循环以关键字for开头。与条件语句类似,迭代语句也由两个主要部分组成:循环头和循环体。
让我们通过刚才运行的for循环来剖析这些部分。
循环头是包含for关键字并以冒号结尾的那一行。它告诉Python开始一个循环。循环头由以下部分组成:
for关键字- 一个循环变量
- 循环将要遍历的序列
循环变量是一个用于控制循环迭代的变量。它紧跟在for后面。一个常见的命名是字母i,但你可以给它起任何你想要的名称。在for循环中,这个临时变量只在循环内部使用,不会在代码的其他部分使用。
循环变量后面是in操作符,以及循环将要遍历的序列。在我们之前的例子中,这个序列是一个包含数字1到4的列表。循环会让这些数字中的每一个都执行指定的操作。
请记住,必须在循环头的末尾加上冒号,以引入后续的代码。
循环体指的是循环头之后缩进的行。这些行代表了循环迭代时要重复执行的操作。在我们这个例子中,它将打印列表中的每个数字:先是1,然后是2,依此类推。
结合range函数使用for循环
for循环的另一个重要用途是,将特定过程重复执行设定的次数。这可以通过结合range函数来实现。
range函数会生成一个数字序列。例如,range(0, 10)会设定一个从0开始,一直到9的序列。
当我们使用range时,我们从第一个位置的数字开始计数(在这个例子中是0)。当我们到达第二个位置的数字时,它告诉我们停止的位置,但这个数字本身被排除在外。所以在这个例子中,数字是10,序列只到9。
关于range函数的一个重要细节是:如果我们不提供起始点,它会自动从0开始。range(10)中的10代表停止点。由于停止点被排除,序列中包含的数字从0开始,到9结束。一个从0开始到9结束的序列将迭代10次。
让我们运行一个结合了range函数的for循环。
for i in range(10):
print("Cannot connect to the destination.")
我们将使用range(10)来要求Python重复一个动作10次,然后指明我们想要重复的动作——打印一条“无法连接到目标”的错误信息。
运行这段代码,使用for循环结合range函数,我们得以将同一条错误信息重复10次,而无需我们自己一遍又一遍地键入。

总结
本节课中,我们一起学习了迭代语句的语法和结构,并以for循环为例进行了实践。我们了解了循环头和循环体的组成,以及如何利用range函数来控制循环的精确次数。在下一节视频中,我们将介绍另一种迭代语句:while循环。
011:使用while循环

概述
在本节课中,我们将要学习Python中的另一种迭代语句——while循环。我们将了解它的基本结构、工作原理,并通过一个网络安全相关的实际例子来掌握其用法。
上一节我们介绍了Python中的迭代语句,并重点讲解了for循环。迭代语句是重复执行一组指令的代码。
while循环基础
本节中我们来看看while循环。while循环也是一种迭代语句,但它的重复执行是基于一个条件。只要条件为真,循环就会继续执行;当条件变为假时,循环就会停止。
while循环的基本结构如下:
while condition:
# 循环体(要重复执行的代码)
与for循环不同,while循环的头部由关键字while、一个条件和一个冒号组成。条件必须是一个布尔表达式(结果为True或False)。循环变量需要在编写while循环之前进行赋值,然后在循环条件中引用它。
例如,以下循环将在变量time小于等于10时持续运行:
time = 0
while time <= 10:
print(time)
time = time + 2
在这个例子中,循环会打印出所有小于等于10的偶数。注意,我们需要在循环体内明确地改变循环变量time的值(每次增加2),否则循环可能会无限进行下去。
实践案例:监控设备连接数
现在我们已经了解了while循环的基础知识,让我们探索一个实际应用场景。想象一下,我们需要限制用户可以连接的设备数量。我们可以使用while循环在用户达到最大连接设备数时打印消息。
以下是实现此功能的步骤:
- 初始化变量:在循环开始前,我们需要设置最大设备连接数和循环变量。
- 构建循环条件:循环将一直运行,直到循环变量不小于最大设备数。
- 定义循环体:在循环内部,执行相关操作(例如打印状态信息)并更新循环变量。
- 处理循环结束:循环结束后,执行后续操作。
让我们用代码来实现这个逻辑:
# 1. 初始化变量
max_devices = 5 # 最大连接设备数
i = 1 # 循环变量,表示当前已连接设备数
# 2. & 3. while循环
while i < max_devices:
print("用户仍可连接更多设备。")
i = i + 1 # 模拟用户连接了一个新设备
# 4. 循环结束后
print("用户已达到最大连接设备数。")
运行这段代码,第一条消息会打印四次。当i的值增加到5时,循环条件i < max_devices变为假,循环停止,然后打印出第二条消息。
总结
本节课中我们一起学习了while循环。我们了解到,while循环是一种基于条件进行重复执行的迭代语句。它的核心结构是while condition:,并且需要在循环体内管理循环变量的变化以避免无限循环。通过一个限制设备连接数的网络安全示例,我们实践了如何应用while循环来解决实际问题。


当你将for循环、while循环的新知识与之前学过的条件语句和变量结合起来时,你在Python中将拥有非常强大的工具来解决各种自动化任务。
012:总结

概述
在本节课中,我们学习了安全分析师为何使用Python,以及程序的基本结构。我们甚至解读了一些Python代码行。现在,让我们回顾一下到目前为止所学的内容。
课程内容回顾
上一节我们介绍了迭代语句,现在我们来总结整个单元的核心知识点。
以下是本单元涵盖的主要知识点列表:
- 编程基础与重要性:你首先学习了编程的基础知识,以及它为何成为安全分析师非常重要的工具。你还了解了一些关于编程语言工作原理的基本概念。
- Python数据类型:接着,你学习了识别Python中的数据类型。我们重点介绍了字符串、整数、浮点数、布尔值和列表。
- 变量:之后,我们重点学习了如何使用变量。
- 条件语句:然后,你全面了解了条件语句,以及如何使用Python语句检查逻辑条件。
- 迭代语句:最后,我们学习了迭代语句,并讨论了
for循环和while循环这两种循环类型。

总结与展望
本节课中,我们一起学习了Python编程的核心基础,包括数据类型、变量、条件判断和循环。这些知识将伴随你继续学习本课程,并在你作为安全分析师的职业生涯中发挥作用。
在接下来的章节中,我们将探索Python的其他重要组成部分,包括函数。
013:欢迎来到第二周 🚀

在本节课中,我们将继续Python编程之旅,学习如何编写更高效、更专业的脚本。我们将重点介绍函数、模块与库,以及提升代码可读性的最佳实践。
欢迎回到我们的Python学习之旅。在之前的视频中,我们已经学习了Python的所有基础知识。
我们从最基础的部分开始,了解了安全分析师如何使用Python。
我们学习了Python的几个基础构建模块。我们详细学习了数据类型、变量和基本语句。
现在,我们将在此基础上更进一步,学习如何编写更高效的Python脚本。我们将探索如何让我们的工作更有效率。
接下来的视频将首先介绍函数,这在Python中非常重要。函数允许我们将一组指令组合在一起,以便在代码中反复使用。
之后,我们将学习Python模块和库。它们包含了我们可以与Python一起使用的函数和数据类型的集合。它们帮助我们获得现成的函数,而无需我们自己创建。
最后,我们将讨论编程中最重要的规则之一,即代码可读性。我们将学习如何确保每个人都能理解并使用你的代码。
我很高兴你决定继续与我一起探索Python。那么,让我们开始学习更多内容吧。

总结
本节课中,我们一起回顾了Python基础,并预告了接下来的学习重点:函数、模块与库以及代码可读性。掌握这些概念将帮助你构建更强大、更易于维护的自动化安全脚本。
014:函数入门

在本节课中,我们将要学习Python编程中的一个核心概念:函数。我们将了解函数是什么、为什么它们如此重要,以及如何在你的代码中使用它们来提高效率和可维护性。
概述:什么是函数?
随着程序复杂度的增长,我们很可能会重复使用相同的代码行。多次编写相同的代码会非常耗时。幸运的是,我们有一种方法来管理这种情况:我们可以使用函数。
一个函数是一段可以在程序中重复使用的代码。
函数的必要性
我们已经学习过一个函数:当我们使用 print 时,我们用它来将指定的数据输出到屏幕。例如,我们打印了 hello Python。但Python中还有许多其他函数。
有时,我们需要自动化一个任务,如果手动完成,这个任务可能会变得重复。之前,我们将Python的其他关键组件比作厨房中的元素。我们将数据类型比作食物的类别。我们处理蔬菜和肉的方式不同,同样,我们处理不同数据类型的方式也不同。
我们讨论过变量就像餐后存放食物的容器,它们所容纳的东西可以改变。至于函数,我们可以把它们想象成洗碗机。如果你不使用洗碗机,你将花费大量时间单独清洗每个盘子。但洗碗机自动化了这个过程,让你可以一次性清洗所有东西。类似地,函数提高了效率。它们在程序中执行重复性的活动,并让程序有效地工作。
函数的工作原理与优势
函数被设计为在我们的程序中重复使用。它们由小的指令组成,可以在程序中的任何地方被调用任意次数。
函数的另一个好处是,如果我们必须对它们进行更改,我们可以直接在函数中进行修改,这些更改将应用到我们使用该函数的所有地方。这比在程序中的许多不同地方进行相同的更改要好得多。
print 函数是一个内置函数的例子。内置函数是存在于Python内部、可以直接调用的函数。它们默认对我们可用。
我们也可以创建自己的函数。用户自定义函数是程序员为其特定需求设计的函数。
函数类型总结
上一节我们介绍了函数的基本概念和优势,本节中我们来看看函数的两种主要类型。
以下是两种主要的函数类型:
- 内置函数:例如
print(),是Python语言自带的,可以直接使用。 - 用户自定义函数:由程序员根据特定需求创建的函数。
这两种类型的函数都像是大型程序中的迷你程序。它们使Python工作变得更加有效和高效。

总结
本节课中我们一起学习了Python函数的基础知识。我们了解到函数是一段可重用的代码,能够极大地提高编程效率和代码的可维护性。我们探讨了函数的必要性,将其比作自动化任务的“洗碗机”。我们还区分了内置函数和用户自定义函数,认识到它们都是构建有效程序的重要工具。在接下来的课程中,我们将继续深入学习如何创建和使用自定义函数。
015:创建一个基本函数

在本节课中,我们将要学习如何创建和运行一个非常简单的用户自定义函数。我们将从定义函数开始,然后调用它来执行特定的任务。
定义函数
上一节我们介绍了用户自定义函数的概念,本节中我们来看看如何具体定义一个函数。定义函数就是告诉Python这个函数的存在。为此,我们需要使用 def 关键字。
以下是定义一个函数的基本步骤:
- 使用
def关键字。 - 为函数命名。
- 在函数名后添加括号
()。 - 在行末添加冒号
:。 - 在缩进的代码块中编写函数要执行的语句。
让我们创建一个在员工登录后向其问候的函数。首先,我们通过注释说明代码的意图。
# 定义一个问候员工的函数
def greet_employee():
print("欢迎登录!")
在这段代码中,def 是定义函数的关键字,greet_employee 是我们为函数起的名字。括号 () 目前是空的,因为我们这个简单的函数不需要接收任何外部信息。冒号 : 表示函数头的结束,其后的缩进代码 print("欢迎登录!") 是函数被调用时会执行的操作。
调用函数
仅仅定义函数并不会让它运行。就像我们之前使用过的 print() 内置函数一样,我们需要“调用”函数来执行它里面的代码。
以下是调用我们刚刚定义的函数的方法:
# 调用问候员工的函数
greet_employee()

当我们运行包含定义和调用的完整代码时,控制台就会输出我们预设的欢迎信息。
总结

本节课中我们一起学习了如何创建和运行一个基本的Python函数。我们首先使用 def 关键字定义了一个名为 greet_employee 的函数,它执行打印欢迎信息的操作。随后,我们通过写出函数名加括号 greet_employee() 的方式调用了这个函数,从而成功输出了消息。这是一个简单函数的完整流程。接下来,我们将学习如何让函数变得更复杂和实用。
016:在函数中使用参数


在本节中,我们将学习如何在Python函数中使用参数。参数允许函数接收外部信息,从而使函数的功能更加灵活和强大。我们将通过定义和调用带参数的函数来掌握这一核心概念。
概述
之前,我们定义并调用了第一个函数。那个函数不需要从外部获取任何信息。但其他函数可能需要。这意味着我们需要讨论如何在函数中使用参数。
在Python中,参数是包含在函数定义中供该函数内部使用的对象。参数通过函数名后的括号被函数接收。我们在上一个视频中创建的函数没有接收任何参数。
现在,让我们回顾另一个使用参数的函数——range函数。如果你还记得,range函数会生成一个从起点到终点前一个值的数字序列。因此,range函数包含了用于起始和结束索引的参数,每个参数都接受一个整数值。
例如,它可以接受整数3和7。这意味着它生成的序列将从3运行到6。
定义带参数的函数
在我们的上一个例子中,我们编写了一个在有人登录时显示欢迎信息的函数。如果我们在信息中加入员工的名字,欢迎效果会更好。
让我们定义一个带参数的函数,以便我们可以按名字问候员工。
当我们定义函数时,我们将包含函数所依赖的参数名称。我们将这个参数(name变量)放在括号内。其余的语法保持不变。
def greet_employee(name):
现在,让我们转到下一行并缩进,以便告诉Python我们希望这个函数做什么。我们希望打印一条使用传入函数的name来欢迎员工的信息。
将变量引入我们的打印语句需要考虑几点。和之前一样,我们从想要打印的欢迎信息开始。但在这种情况下,我们不会在告诉他们已登录后就停止信息。我们希望继续并将员工的名字添加到信息中。
这就是为什么我们在“you are logged in”后面加一个逗号,然后添加name变量。由于这是一个变量而不是特定的字符串,我们不用引号括住它。
def greet_employee(name):
print("Welcome, you are logged in,", name)
调用函数并传递参数
现在我们的函数已经设置好,我们准备用一个特定的参数来调用它。
在Python中,参数是在调用函数时带入函数的数据。例如,之前我们将3和7传递给range函数,这些就是参数。
在我们的例子中,假设我们想问候一位名叫Charlie Patel的员工。我们将用这个参数调用我们的greet_employee函数。
greet_employee("Charlie Patel")
当我们运行这段代码时,Charlie Patel会收到一条个性化的欢迎信息。
使用多个参数
在这个例子中,我们的函数只有一个参数。但我们也可以有更多参数。让我们探索一个这样的例子。
也许我们不是只有一个name参数,而是有一个first_name参数和一个last_name参数。如果是这样,我们需要像这样调整代码。
首先,当我们定义函数时,我们包含两个参数并用逗号分隔它们。
def greet_employee_fullname(first_name, last_name):
然后,当我们调用它时,我们也包含两个参数。这次,我们问候一位名叫Kiara Karu的人。这些参数也用逗号分隔。
greet_employee_fullname("Kiara", "Karu")
让我们运行这些代码来欢迎Kiara Karu。正如我们刚刚探索的,使用多个参数只需要进行一些调整。
以下是完整的代码示例:
def greet_employee_fullname(first_name, last_name):
print("Welcome, you are logged in,", first_name, last_name)
greet_employee_fullname("Kiara", "Karu")
总结

在本节中,我们一起学习了如何在函数中使用参数。我们了解到参数是函数定义的一部分,用于接收外部数据,而参数是在调用函数时实际传递的数据。我们实践了如何定义带有一个和多个参数的函数,并成功地调用了它们。掌握参数的使用对于编写灵活、可重用的Python脚本至关重要。

本节视频中我们学习了大量关于在函数中使用参数的知识。😊 这种理解在你继续编写Python脚本时将必不可少。
017:返回语句


在本节课中,我们将学习如何从函数中返回信息。我们将了解return语句的作用,并通过一个计算登录失败率的网络安全相关示例来演示其用法。
概述
之前我们学习了如何向函数传递参数。实际上,函数不仅能接收信息,还能向外发送信息。return语句使我们能够实现这一点。它是一个在函数内部执行的Python语句,用于将信息发送回函数调用处。对于安全分析师而言,从函数返回信息的能力有多种用途。例如,分析师可能编写一个函数来检查某人是否有权访问特定文件,并向主程序返回一个布尔值(True或False)。
接下来,我们将探索另一个示例,创建一个与分析登录尝试相关的函数。
创建返回信息的函数
上一节我们介绍了如何向函数传递参数,本节中我们来看看如何让函数计算结果并返回给我们。
我们将创建一个函数,根据传入的信息计算登录失败的百分比,并返回这个百分比。程序可以多种方式使用这个信息,例如,决定是否锁定账户。
以下是创建此函数的步骤:
- 定义函数:我们首先定义一个名为
calc_fails的函数。 - 设置参数:该函数将设置两个与登录尝试相关的参数:
total_attempts(总尝试次数)和failed_attempts(失败次数)。 - 计算百分比:在函数体内,我们将失败次数除以总次数,得到失败百分比,并将其存储在变量
fail_percentage中。 - 使用
return语句:最后,我们使用关键字return将fail_percentage变量的值返回给调用者。
让我们用代码来具体实现:
def calc_fails(total_attempts, failed_attempts):
fail_percentage = failed_attempts / total_attempts
return fail_percentage
调用函数并处理返回值
定义好函数后,我们就可以调用它了。假设一个用户登录了4次,其中2次失败。
直接调用函数calc_fails(4, 2)会进行计算并返回值0.5(即50%)。但在某些Python环境中,这个返回值可能不会自动显示在屏幕上。
更重要的是,在函数外部无法直接使用函数内部定义的变量名(如fail_percentage)。为了在程序的其他部分使用这个计算结果,我们需要将函数的返回值赋给一个新的变量。
以下是正确处理返回值的示例:
# 调用函数,并将返回值存储在变量 `percentage` 中
percentage = calc_fails(4, 2)
# 现在可以在后续代码中使用这个变量
if percentage >= 0.5:
print("账户已锁定")
运行这段代码,我们不会直接看到百分比数值被打印出来,而是会根据条件判断输出“账户已锁定”的消息。这演示了如何将函数的返回值集成到更复杂的程序逻辑中。
总结
本节课中我们一起学习了return语句。我们了解到,return关键字用于从函数中返回信息,这使得函数不仅能执行任务,还能输出结果供程序其他部分使用。我们通过一个计算登录失败率并据此决定是否锁定账户的网络安全示例,实践了如何定义返回值的函数以及如何接收和使用返回值。


接下来,我们将讨论更多关于函数的内容。不过下一次,我们将重点介绍一些Python内置的、可以直接使用的函数。
018:探索内置函数 🐍

在本节课中,我们将要学习Python的内置函数。我们将回顾一些已学过的函数,并探索几个新的内置函数,了解它们的输入、输出以及如何组合使用它们。
回顾已学的内置函数
上一节我们学习了如何创建自定义函数。本节中,我们来看看Python提供的一些内置函数。
内置函数是Python中预先定义好的函数,我们可以直接调用它们。我们只需要知道它们的名称即可。在之前的课程中,我们已经接触过两个内置函数:print 和 type。让我们快速回顾一下。
print函数:将指定的对象输出到屏幕。type函数:返回其输入参数的数据类型。
组合使用函数
之前,我们通常是独立地使用这些函数。例如,单独调用 print 或 type。随着我们开始深入学习函数,经常需要将多个函数组合在一起使用。
我们可以通过将一个函数作为参数传递给另一个函数来实现这一点。例如,在下面这行代码中:
print(type("hello"))
Python首先会执行内部的 type("hello"),返回字符串 "hello" 的数据类型(<class 'str'>)。然后,这个返回值会作为参数传递给外层的 print 函数。最终,字符串的数据类型会被打印到屏幕上。
print 和 type 并不是唯一可以这样组合使用的函数。在所有情况下,其通用语法是相同的:先处理内部函数,然后将其返回值传递给外部函数。
理解函数的输入与输出
使用函数时,必须理解它们期望的输入和产生的输出。
有些函数只接受特定的数据类型,如果使用错误类型,会返回类型错误。另一些函数可能需要特定数量的参数,或者会返回不同类型的数据。
以下是关于 print 和 type 函数输入输出的分析:
print函数:可以接受任何数据类型作为输入,也可以接受任意数量的参数,即使这些参数的数据类型各不相同。type函数:可以接受所有数据类型,但它只接受一个参数。
让我们通过代码来探索 print 函数的输入和输出。我们将传入三个参数:
print("The number is", 2023, ".")
运行这段代码,它会按预期打印出所有内容。
现在,让我们探索 type 函数的输入和输出:
print(type("security"))
print(type(73.2))
运行这段代码,Python首先告诉我们单词 "security" 是字符串类型,接着告诉我们 73.2 是浮点数类型。
在使用内置函数之前,我们必须确切知道它需要多少个参数、参数可以是哪些数据类型,以及它会产生什么样的输出。
学习新的内置函数
了解了这些注意事项后,让我们来学习两个新的内置函数。
max 函数
max 函数返回传入的数值参数中的最大值。它没有定义可接受参数的具体数量。
以下是使用 max 函数的示例:
a = 3
b = 9
c = 6
print(max(a, b, c))
运行这段代码,它会告诉我们这些值中最大的是 9。
sorted 函数
sorted 函数对列表中的元素进行排序。在网络安全场景中处理列表时,这个函数非常有用。
对于数字列表,我们可以将其从小到大(或从大到小)排序。对于字符串列表,我们可能需要按字母顺序排序。例如,假设你有一个包含组织中用户名的列表,并且你想按字母顺序对其进行排序。
让我们使用Python的 sorted 函数来实现:
usernames = ["zkeller", "wjaffrey", "ptran", "dnguyen"]
print(sorted(usernames))

运行这段代码,所有用户名现在都按字母顺序排列好了。
总结

本节课中,我们一起学习了Python的内置函数。我们回顾了 print 和 type 函数,并学习了如何通过将一个函数嵌套在另一个函数中来组合使用它们。我们还探讨了理解函数输入和输出的重要性。最后,我们介绍了两个新的内置函数:用于查找最大值的 max 函数,以及用于对列表进行排序的 sorted 函数。这些只是Python众多内置函数中的一小部分,随着你在Python中深入实践,你会熟悉更多能在程序中帮助你的函数。
019:模块与库

概述
在本节课中,我们将要学习Python中的模块与库。它们是包含预编写代码的文件集合,能帮助我们更高效地完成编程任务,特别是在处理网络安全相关的数据分析时。
从函数到模块
上一节我们介绍了如何在Python中构建和使用函数。Python自带了许多内置函数,例如 print()、type() 和 max()。
为了使用更多预先编写好的功能,我们可以导入库。库是模块的集合,为程序提供了可访问的额外代码。
理解模块与库
所有库通常由多个模块组成。模块是一个Python文件,其中包含额外的函数、变量、类以及任何可运行的代码。你可以将它们视为保存了有用功能的Python文件。
模块的代码可能简短,也可能复杂冗长。无论如何,它们都能帮助程序员节省时间,并使代码更具可读性。
Python标准库
现在,让我们具体关注Python标准库。它是一个庞大的、可用的Python代码集合,通常随Python一起安装。
以下是Python标准库中的几个模块示例:
re模块:这是一个对安全分析师非常有用的模块,当需要搜索日志文件中的模式时可以使用它。csv模块:它允许你高效地处理CSV文件。sys和os模块:用于与命令行交互。time和datetime模块:用于处理时间戳。

这些只是Python标准库中的一小部分模块。
外部库
除了Python标准库中始终可用的内容,你还可以下载外部库。以下是两个例子:
beautifulsoup4:用于解析HTML网页文件。numpy:用于数组和数学计算。
这些库将协助你作为安全分析师进行网络流量分析、日志文件解析和复杂数学运算。
总结
本节课中我们一起学习了Python的模块与库。总的来说,Python库和模块非常有用,因为它们提供了预先编程好的函数和变量,这为用户节省了大量时间。我们鼓励你探索我们在这里讨论的一些库和模块,并思考它们在你使用Python工作时可能带来的帮助。
020:代码可读性


在本节课中,我们将要学习如何编写易于阅读和维护的Python代码。我们将探讨代码可读性的重要性,并介绍一些关键的指导原则,特别是PEP 8风格指南。
概述:为什么代码可读性很重要
编写代码不仅是为了让计算机执行,更是为了让其他人(包括未来的自己)能够理解。Python因其可读性强而广受欢迎,而遵循社区公认的风格指南能确保代码的整洁和一致。
代码风格指南
上一节我们介绍了代码可读性的基本概念,本节中我们来看看什么是风格指南。
风格指南是一份手册,用于指导文档的编写、格式和设计。在编程领域,风格指南旨在帮助程序员遵循相似的约定。
PEP 8 是为Python程序员提供的风格指南资源。PEP是“Python增强提案”的缩写。PEP 8为程序员提供了与语法相关的建议。这些建议不是强制性的,但它们有助于在程序员之间建立一致性,确保其他人能轻松理解我们的代码。其核心原则是:代码被阅读的次数远多于被编写的次数。
对于任何希望以与其他程序员一致的方式风格化和格式化其Python代码的人来说,PEP 8都是一个极好的资源。
注释
PEP 8讨论了注释的使用。注释是程序员对其代码意图所做的说明。它们被插入到计算机程序中,以指示代码在做什么以及为什么这样做。
以下是PEP 8的一些具体建议:
- 使你的注释清晰明了。
- 当代码更改时,保持注释的更新。
以下是一个没有注释的代码示例:
failed_attempts = 6
if failed_attempts > 5:
print(“Account locked”)
编写这段代码的人可能知道发生了什么,但其他需要阅读它的人呢?他们可能不理解 failed_attempts 变量背后的上下文,以及为什么当它大于5时会打印“Account locked”。即使原作者将来为了开发更大的程序而需要重新审视这段代码,没有注释也会降低效率。
在这个例子中,我们添加了注释:
# 检查登录失败次数,超过5次则锁定账户
failed_attempts = 6
if failed_attempts > 5:
print(“Account locked”)
现在,其他读者可以快速理解我们的程序及其变量在做什么。注释应该简短且切中要点。
缩进
接下来,让我们谈谈代码可读性的另一个重要方面:缩进。
缩进是在一行代码开头添加的空格。这既能提高可读性,又能确保代码正确执行。在某些情况下,你必须缩进行代码以建立与其他行代码的连接。这些缩进的代码行组成一个代码块,并与前面未缩进的行代码建立联系。

条件语句的主体就是一个例子:
updates_needed = True
if updates_needed:
print(“System updates are required.”)
我们需要确保 print 语句仅在条件满足时执行。这里的缩进为Python提供了这个指令。如果 print 语句没有缩进,Python将在条件语句之外执行它,导致它总是被打印。这将产生问题,因为你会收到一条需要更新的消息,即使实际上并不需要。
要进行缩进,你必须在代码行前添加至少一个空格。通常,程序员为了视觉清晰会添加两到四个空格。PEP 8指南建议使用四个空格。
实践中的重要性
在我的第一份工程工作中,我编写了一个脚本来帮助验证和启动防火墙规则。起初,我的脚本运行良好,但一年后当我们试图扩展其功能时,它变得难以阅读。在那一年里,我的编程知识和编码风格以及我队友的编码实践都发生了变化。当时我们的组织没有使用编码风格指南,所以我们的代码差异很大,难以阅读,并且扩展性不好。这带来了很多挑战,需要额外的工作来修复。
确保代码可读且能够随时间修改,这就是为什么安全专业人员遵循编码风格指南很重要,也是为什么风格指南对组织来说如此重要。
总结
在本节课中,我们一起学习了Python代码可读性的关键要素。我们了解了PEP 8风格指南的作用,学习了如何编写清晰的注释,以及如何使用正确的缩进来组织代码结构。编写可读的代码是使用Python进行工作的关键能力。
随着我们进入课程的下一部分,我们将继续培养有效的编码实践,以追求更好的可读性。
021:在网络安全团队中高效使用Python

概述
在本节课中,我们将跟随安全工程师多尔萨,学习如何在网络安全团队中高效地使用Python进行协作开发。我们将探讨团队协作的重要性、代码规范的价值以及如何通过沟通和利用外部资源来提升个人与团队的工作效率。
团队协作与反馈的重要性
上一节概述了课程主题,本节中我们来看看团队协作的核心。多尔萨是一名安全工程师,她工作中最喜爱的是每天都能接触不同的基础设施和系统设计。
对于刚进入网络安全领域的人,她给出了一条关键建议:在Python开发中协同工作至关重要,而其中的一个关键方面是倾听团队成员提供的反馈。
共享代码与统一规范
理解了团队协作的重要性后,我们来看看具体实践。在团队成员之间共享Python代码片段时,Python提供了多种访问不同信息的方式。
以下是共享代码带来的两个主要好处:
- 它使代码更加统一,编码过程更高效。
- 它使代码库更具可读性,并允许其他工程师在你之后继续处理你的代码。
协作编程的成功案例
为了更具体地说明协作的价值,多尔萨分享了一个行业内的成功案例。她见过许多协作编写Python代码在行业中发挥作用的例子。
其中一个例子是在谷歌,他们编写了一个协作代码库,使得入职流程从6或7小时减少到几分钟。协作是这个过程中的关键部分,否则单靠一个人编写可能需要很多年。一个人无法理解每个系统的所有细节,如果没有多个工程师共同工作,这个过程会困难得多。
沟通与资源共享
从成功案例中我们看到,沟通是协作的基石。在团队中工作时,沟通非常重要,特别是如果你在用Python开发代码。你需要表达在整个过程中是否需要帮助,因为你的团队成员的存在是为了确保你最终能成功。归根结底,你的成功也意味着你的团队是成功的。
随着你作为Python代码编写者职业生涯的发展,你会意识到网上存在大量现成的函数和方法。通过快速搜索就能找到它们,这些方法会派上用场,你可以将它们重用于你的代码中。

除了利用网络资源,提升技能还有另一个有效途径。一个让你学习新技能、扩展Python编码能力的绝佳资源是与你的同事交流、参加技术聚会、与不在你公司工作的其他安全专业人士交谈。因为每个人对于如何提升你的编码技能(尤其是在网络安全领域)都有独到的见解。
总结
本节课中,我们一起学习了在网络安全团队中使用Python进行高效协作的关键要点。我们认识到倾听反馈、统一代码规范、积极沟通以及利用内外资源(如团队智慧和网络代码片段)对于提升个人效率和团队整体成功至关重要。记住,在网络安全领域,协作不仅是写好代码的方式,更是应对复杂系统挑战的必需策略。
022:总结

在本节课中,我们将回顾并总结你在Python课程中学到的核心概念。你已经投入了大量精力来学习如何高效地使用Python,现在让我们快速重温一下这些关键知识点。
🧩 核心概念回顾
上一节我们介绍了代码可读性和最佳实践,本节中我们来整体回顾整个课程的核心内容。
以下是你在本阶段课程中学到的三个主要部分:
-
函数的作用
你首先理解了函数在Python中的角色。函数可以节省大量时间。你学习了如何构建函数,以及如何开发自定义函数来满足特定需求。定义一个函数的基本语法是:def function_name(parameters): # 函数体 return result -
模块与库
随后,我们的焦点转向了模块和库。它们让你能够访问比Python内置函数多得多的功能。你可以使用import语句来引入它们:import module_name from library import specific_function -
代码可读性与最佳实践
最后,我们学习了代码可读性和编写清晰、易懂代码的最佳实践。这包括使用有意义的变量名、添加注释以及保持一致的代码风格。
🚀 展望未来

掌握了这些知识后,你已经为学习Python在任务自动化方面的强大能力做好了准备。你将进一步了解它如何能帮助你在未来成为一名安全分析师。
感谢你花时间与我一起完成这门课程。我们将在接下来的视频中再见。😊
本节课中我们一起学习了:Python函数的基础、模块与库的使用,以及编写可读性高、符合最佳实践的代码。这些是使用Python进行高效自动化,特别是网络安全任务自动化的基石。
023:欢迎来到第三周 🚀

在本节课中,我们将学习如何更高效地处理网络安全工作中的数据。我们将深入探索字符串和列表的操作,学习编写解决安全问题的算法,并初步接触强大的正则表达式工具。
作为一名安全分析师,你将处理大量数据。能够开发管理这些数据的解决方案非常重要。我们即将在Python中学到的内容将对此大有裨益。
在上一节中,我们为本章节的学习打下了基础。我们学习了所有关于数据类型和变量的知识,也涵盖了条件语句和循环语句。我们还学习了如何构建函数,甚至创建了自己的函数。
本节中,我们将在几个不同的方面继续深入。
首先,你将学习更多关于处理字符串和列表的知识。我们将扩展你处理这些数据类型的方式,包括从字符串中提取字符或从列表中提取项目。
我们的下一个重点是编写算法。你将学习一套可以在Python中应用的规则,以解决与安全相关的问题。
最后,在探索使用正则表达式时,我们将进一步扩展搜索字符串的方法。
我们将有很多乐趣,并开始编写一些真正有趣的Python代码。😊
我迫不及待要开始了。

本节课中,我们一起学习了第三周的学习目标和内容概览。我们明确了本周将重点提升数据处理能力,包括更高级的字符串和列表操作、算法编写以及正则表达式的引入,这些都是自动化网络安全任务的核心技能。
024:字符串操作

概述
在本节课中,我们将学习如何在Python中处理字符串数据。字符串操作是网络安全任务中的一项基础且重要的技能,例如分析用户名模式或验证IP地址格式。我们将从字符串的基础知识开始,逐步介绍如何创建字符串、获取其长度、连接字符串以及使用字符串方法。
字符串基础回顾
上一节我们介绍了Python中的基本数据类型。本节中,我们来看看字符串类型。
字符串是由字符组成的序列数据。在Python中,字符串写在引号内,可以使用单引号或双引号。本课程中我们主要使用双引号。
示例:
"hello"
"1,2,3"
"number one"
变量可以用于存储字符串。
my_string = "security"
数据类型转换
有时我们需要将其他数据类型(如整数或浮点数)转换为字符串。为此,我们引入一个新的内置函数:str() 函数。
str() 函数将输入对象转换为字符串。将对象转换为字符串后,我们可以执行一些仅适用于字符串的操作,例如删除或重新排序其中的字符,这些操作对于整数数据类型来说很困难。
示例:将整数转换为字符串
new_string = str(123)
print(type(new_string))
运行上述代码,new_string 变量将包含字符串 "123",type() 函数会确认其类型为字符串。
基本字符串操作
现在我们已经知道如何创建和存储字符串,接下来让我们探索一些基本的字符串操作。
获取字符串长度
len() 函数返回对象中元素的数量。对字符串使用此函数可以告诉我们字符串包含多少个字符。
在网络安全中,此功能很有用。例如,IPv4地址最多有15个字符。安全专业人员可以使用 len() 函数来检查一个IPv4地址是否有效:如果其长度超过15个字符,则可以判定为无效的IPv4地址。
示例:获取字符串长度
print(len("hello"))
运行代码,输出为 5,对应单词 “hello” 中的五个字母。
字符串连接
我们可以对字符串使用加法运算符,这称为字符串连接。字符串连接是将两个字符串合并在一起的过程。
示例:连接字符串
print("hello" + "world")
运行后,我们得到 helloworld。请注意,两个字符串之间没有自动添加空格。
需要注意的是,并非所有运算符都适用于字符串。例如,不能使用减号来“减去”两个字符串。
字符串方法
方法是属于特定数据类型的函数。因此,在另一种数据类型(如整数)上使用字符串方法会导致错误。与其他函数不同,方法出现在字符串之后。
以下是两种常见的字符串方法:
upper() 方法
upper() 方法返回一个所有字母均为大写的新字符串副本。
示例:使用 upper() 方法
print("hello".upper())
注意方法的独特语法:在字符串 "hello" 后加一个点 .,然后指定要使用的方法 upper()。运行后,屏幕输出 HELLO。
lower() 方法
lower() 方法返回一个所有字母均为小写的新字符串副本。
示例:使用 lower() 方法
print("HELLO".lower())
将字符串和方法放在 print() 函数中以输出结果。运行后,屏幕输出 hello。
总结

本节课中,我们一起学习了Python中字符串操作的基础知识。我们回顾了字符串的定义和创建方式,学习了如何使用 str() 函数进行类型转换。接着,我们探索了如何用 len() 函数获取字符串长度,以及如何使用 + 运算符进行字符串连接。最后,我们介绍了字符串方法,特别是 upper() 和 lower() 方法的使用。掌握这些基础操作是进行更复杂字符串处理(如索引和分割)的重要前提。在接下来的课程中,我们将继续深入学习字符串的更多功能。
025:Python中的字符串索引和切片

概述
在本节课中,我们将要学习Python中字符串的索引和切片操作。这些是处理文本数据的基础技能,对于网络安全分析师来说至关重要,例如在日志文件中搜索特定信息。
字符串索引
上一节我们介绍了字符串处理的重要性。本节中我们来看看如何定位字符串中的单个字符。
在Python中,字符串中的每个字符都有一个对应的索引,用于指示其位置。索引从0开始计数。
公式:字符串[索引]
例如,字符串 "hello" 的索引分配如下:
"h"的索引是0"e"的索引是1"l"的索引是2"l"的索引是3"o"的索引是4
在代码中,我们可以通过将索引放在方括号 [] 中来访问特定位置的字符。
my_string = "hello"
print(my_string[1]) # 输出: e
字符串切片
了解了如何访问单个字符后,我们来看看如何提取字符串的一部分,这称为切片。
切片允许我们通过指定起始和结束索引来获取一个子字符串。起始索引包含在结果中,而结束索引不包含在结果中。
公式:字符串[起始索引:结束索引]
例如,要从 "hello" 中提取 "ell",我们需要从索引 1 开始,到索引 4 之前结束。
my_string = "hello"
print(my_string[1:4]) # 输出: ell
使用 index() 方法搜索字符串
作为网络安全分析师,我们经常需要在字符串中搜索特定内容。Python提供了 index() 方法来帮助我们。
index() 方法用于查找某个子字符串或字符在字符串中第一次出现的位置,并返回其索引。
以下是 index() 方法的使用步骤:
- 在目标字符串后调用
.index()方法。 - 将要查找的字符或子字符串作为参数传入。
my_string = "hello"
position = my_string.index("e")
print(position) # 输出: 1
需要注意的是,字符串在Python中是区分大小写的。同时,如果字符重复出现,index() 方法只返回第一次出现的位置。
my_string = "hello"
position = my_string.index("l")
print(position) # 输出: 2 (第二个 ‘l’ 的索引是 3,但不会被返回)
字符串的不可变性
在探讨了如何查找和提取字符串内容后,我们需要了解字符串的一个重要特性:不可变性。
在Python中,不可变意味着一个对象在创建并被赋值后,其内容不能被改变。
让我们通过一个例子来理解。尝试直接修改字符串中的某个字符会导致错误。
my_string = "hello"
# 尝试将 ‘e’ 改为 ‘a’
my_string[1] = "a" # 这行代码会引发 TypeError 错误

以上操作会失败,因为字符串 my_string 是不可变的。你不能像修改列表元素那样直接通过索引来修改字符串中的字符。

总结
本节课中我们一起学习了Python字符串处理的核心操作。我们掌握了如何使用索引访问单个字符,如何使用切片提取子字符串,以及如何利用 index() 方法在字符串中搜索内容。最后,我们理解了字符串的不可变性,即字符串一旦创建就不能直接修改其内容。这些基础知识是后续进行更复杂文本分析和日志处理的关键。接下来,我们将学习列表的操作,并会发现列表是可变的,这与字符串不同。
026:Python中的列表操作 📋

概述
在本节课中,我们将学习Python中列表(List)这一重要数据类型。列表允许我们在单个变量中存储多个数据项,这在网络安全领域非常实用,例如管理IP地址列表或记录被阻止的应用程序。我们将探讨如何创建列表、访问元素、修改列表内容以及使用相关方法。
列表的创建与访问
上一节我们介绍了字符串,本节中我们来看看另一种数据类型——列表。
列表非常有用,因为它允许你在单个变量中存储多个数据片段。在安全领域,你会处理各种列表。例如,你可能有一个记录有权访问网络的IP地址列表,另一个列表可能包含系统上被阻止运行的应用程序信息。
让我们回顾如何在Python中创建列表。以下代码创建了一个包含字母A到E的列表:
my_list = ['A', 'B', 'C', 'D', 'E']
列表中的项目用逗号分隔,并用方括号包围。我们可以将列表赋值给一个变量以便后续使用,这里我们将变量命名为my_list。
访问列表中的特定元素时,我们使用的语法与访问字符串中的元素类似。我们将索引值放在存储列表的变量名后面的方括号中。例如,my_list[1]将访问列表中的第二个项目。这是因为在Python中,元素的计数从0开始,而不是1。因此,第一个元素的索引是0,第二个元素的索引是1。
让我们尝试从列表中提取一些元素。我们将通过变量名后加[1]来提取第二个元素,并将其放入print函数以输出结果:
print(my_list[1])
运行后,Python会输出字母B。
列表的拼接
与字符串类似,我们也可以使用加号+来拼接列表。列表拼接是将两个列表合并为一个,方法是将第二个列表的元素直接放在第一个列表的元素之后。
让我们在Python中实践一下。首先,我们定义与之前示例相同的列表,存储在变量my_list中。然后,我们定义另一个包含数字1到4的列表another_list。最后,我们用加号拼接这两个列表并打印结果:
my_list = ['A', 'B', 'C', 'D', 'E']
another_list = [1, 2, 3, 4]
concatenated_list = my_list + another_list
print(concatenated_list)
运行后,我们会得到一个拼接后的最终列表。
列表与字符串的区别
在讨论了相似之处后,现在我们来探索列表和字符串之间的区别。
我们之前提到字符串是不可变的,这意味着一旦定义,它们就不能被更改。而列表则没有这个属性,我们可以自由地更改、添加和删除列表中的值。例如,如果我们有一个恶意IP地址列表,那么每当识别出新的恶意IP地址时,我们可以轻松地将其添加到列表中。
首先,让我们尝试在Python中更改列表中的特定元素。我们从前面的示例中的列表开始。要更改列表中的元素,我们需要结合使用方括号表示法和变量赋值。
假设我们要将my_list中的第二个元素(字符串'B')更改为数字7:
my_list[1] = 7
print(my_list)
我们将要更改的对象放在变量赋值的左侧,这里我们更改my_list的第二个元素。然后,我们放置一个等号表示我们正在重新分配列表的这个元素。最后,在右侧放置要替换的新对象。运行代码后,字母B现在已更改为数字7。
列表元素的插入与移除
现在,让我们看看在列表中插入和移除元素的方法。本视频中我们将使用的第一个方法是insert方法。
insert方法在列表的特定位置添加一个元素。该方法接受两个参数:第一个是我们要添加元素的位置,第二个是我们要添加的元素。
让我们使用insert方法。我们从my_list变量中定义的列表开始。然后,我们输入my_list.insert()并传入两个参数。第一个参数是我们想要插入新信息的位置,这里我们想插入到索引1处。第二个参数是我们想要添加到列表中的信息,这里是整数7:
my_list = ['A', 'B', 'C', 'D', 'E']
my_list.insert(1, 7)
print(my_list)
我们的列表仍然以A(索引为0的元素)开始。现在,我们在下一个位置(索引为1)有了整数7。注意,原本在索引1处的字母B并没有像使用方括号表示法时那样被替换。使用insert方法时,索引1之后的所有元素都简单地向下移动了一个位置,B的索引现在变成了2。
有时我们可能想从列表中移除不再需要的元素。为此,我们可以使用remove方法。remove方法移除列表中第一次出现的特定元素。与insert不同,remove的参数不是索引值,而是直接键入你想要移除的元素。remove方法会移除列表中该元素的第一个实例。
让我们使用remove方法从列表中删除字母D:
my_list.remove('D')
print(my_list)
我们将变量名my_list与remove方法结合使用,并将'D'作为参数传入。运行后,D已从列表中移除。

总结
本节课中我们一起学习了Python列表的基本操作。我们了解了如何创建和访问列表元素,掌握了列表拼接的方法,并重点探讨了列表与字符串的关键区别——列表的可变性。通过insert和remove方法,我们学会了如何在列表中动态地添加和删除元素。就像处理字符串一样,能够熟练搜索和操作列表是安全分析师的一项必备技能。我们期待在接下来的课程中继续扩展对这些概念的理解。😊
027:编写一个简单的算法

概述
在本节课中,我们将学习算法的基本概念,并通过一个网络安全领域的实际例子——从IP地址列表中提取网络前缀——来演示如何用Python设计和实现一个简单的算法。我们将结合循环、列表和字符串切片等已学知识。
什么是算法?🤔
在日常生活中,我们经常遵循规则来解决问题。一个简单的例子是煮咖啡。如果你煮过很多次咖啡,你可能会遵循一个流程:首先,拿起你最喜欢的杯子;然后,将水倒入咖啡机并加入咖啡粉;接着,按下开始按钮并等待几分钟;最后,享受你的新鲜咖啡。
即使你煮咖啡的方法不同或者根本不喝咖啡,你很可能也遵循一套规则来完成类似的日常任务。当你完成这些常规任务时,你就是在遵循一个算法。
算法是一套用于解决问题的规则。更详细地说,算法是一系列步骤,它从问题中获取输入,利用这个输入执行任务,并返回一个解决方案作为输出。
网络安全场景:提取IP地址的网络前缀
上一节我们介绍了算法的概念,本节中我们来看看如何将其应用于网络安全任务。假设你是一名安全分析师,手头有一个IP地址列表。你想提取每个IP地址的前三位数字,这将告诉你这些IP地址所属网络的信息。
为了实现这个目标,我们将编写一个算法,其中会用到我们目前学过的多个Python概念:循环、列表和字符串。
以下是存储为字符串的IP地址列表(出于隐私考虑,示例中不显示完整地址):
IP = ["198.168.1.1", "192.168.2.1", "10.0.0.1"]
我们的目标是提取每个地址的前三个数字,并将它们存储在一个新列表中。
分解问题:从简单情况入手
在编写任何Python代码之前,让我们先分解一下用算法解决这个问题的思路。如果你只有一个IP地址,而不是整个列表,问题会变得简单得多。
第一步是使用字符串切片从一个IP地址中提取前三位数字。
现在,考虑如何将其应用于整个列表。第二步是使用循环将该解决方案应用于列表中的每个IP地址。
实现第一步:字符串切片
之前我们学习过字符串切片。现在,让我们写一些Python代码来解决一个IP地址的问题。
我们从以“198.567”开头的一个IP地址开始,编写几行代码来提取前三个字符:
address = "198.567.xxx.xxx"
print(address[0:3])
我们使用方括号表示法来切片字符串。在print语句中,address变量包含我们要切片的IP地址。请记住,Python从0开始计数,所以要获取前三个字符,我们从索引0开始切片,一直到索引3。Python会排除最终索引,换句话说,它将返回索引0、1和2处的字符。
运行这段代码,我们得到地址的前三位数字:198。
引入新工具:append方法
现在我们已经能够解决一个IP地址的问题,我们可以将这段代码放入循环中,并将其应用于原始列表中的所有IP地址。
在这样做之前,我们先介绍一个将在这段代码中使用的方法:append方法。append方法将输入添加到列表的末尾。
例如,假设my_list包含[1, 2, 3],使用以下代码,我们可以用append方法将4添加到这个列表中:
my_list = [1, 2, 3]
my_list.append(4)
print(my_list) # 输出: [1, 2, 3, 4]
实现第二步:循环应用
现在我们准备好从列表的每个元素中提取前三个字符了。
首先,我们给定IP列表:
IP = ["198.168.1.1", "192.168.2.1", "10.0.0.1"]
创建一个空列表来存储从IP列表中提取的每个地址的前三个字符:
networks = []
现在我们可以开始for循环了。让我们分解一下:
for address in IP:
networks.append(address[0:3])
for告诉Python我们即将开始一个for循环。然后我们选择address作为循环内的变量,并指定名为IP的列表作为可迭代对象。当循环运行时,IP列表中的每个元素将临时存储在address变量中。
在for循环内部,我们有一行代码将address的切片添加到networks列表中。分解来看,我们使用之前编写的代码来获取IP地址的前三个字符,然后使用append方法将一个项目添加到列表的末尾。在这里,我们添加到networks列表。

最后,让我们打印networks列表并运行代码:
print(networks)
运行后,变量networks现在包含了原始IP列表中每个IP地址前三位数字的列表。

总结
本节课中我们一起学习了算法的定义,并通过一个提取IP地址网络前缀的实例,实践了如何将复杂问题分解为更小的步骤。我们首先使用字符串切片处理单个元素,然后利用for循环和append方法将解决方案扩展到整个列表。设计算法可能具有挑战性,因此在着手编写代码之前将其分解成小问题是一个好方法。我们将在后续视频中继续练习这一思想。
028:Python中的正则表达式 🐍

在本节课中,我们将要学习一种更高级的字符串搜索方法:正则表达式。我们将了解其基本概念、核心符号,并学习如何构建模式来从文本(如日志文件)中提取特定信息,例如电子邮件地址。
我们已经学习了很多关于处理字符串的知识,包括使用位置索引和分析切片。在上一节中,我们应用这些知识从IP地址列表中提取了前三位数字。本节中,我们将专注于一种更高级的字符串搜索方式。
正则表达式(常缩写为regex)是一个构成搜索模式的字符序列。这个模式可以在搜索日志文件时使用。我们可以用它来搜索任何类型的模式。例如,我们可以找到所有以特定前缀开头的字符串,或者找到所有特定长度的字符串。
我们可以通过多种方式将其应用于安全场景。例如,假设我们需要找到所有网络ID为184的IP地址。正则表达式将允许我们高效地搜索此模式。
在本视频中,我们将研究另一个例子。假设我们想要提取日志中包含的所有电子邮件地址。如果我们尝试通过索引方法来实现,我们需要知道要搜索的确切电子邮件地址。作为安全分析师,我们很少拥有这类信息。但是,如果我们使用一个告诉Python电子邮件地址结构的正则表达式,我们将返回所有具有与电子邮件地址相同元素的字符串。
即使我们面对一个包含数千行和条目的日志文件,我们也可以通过正则表达式搜索电子邮件地址的结构来提取文件中的每一个电子邮件。我们不需要知道具体的电子邮件地址就能提取它们。
让我们探索实现此功能所需的正则表达式符号。首先,我们来学习加号(+)。
加号(+)是一个正则表达式符号,代表特定字符的一次或多次出现。让我们通过一个示例模式来解释。正则表达式模式 a+ 匹配一个其中字母a重复出现的任意长度的字符串。例如,单个a、连续三个a或连续五个a。它甚至可以是连续1000个a。
我们可以通过一个快速示例来查看此模式将提取哪些字符串。假设我们有一个设备ID字符串列表。这些是字母a出现一次或连续多次的所有实例。第一个实例有1个a,第二个有2个a,第三个有1个a,第四个有3个a。因此,如果我们告诉Python查找与正则表达式 a+ 匹配的内容,它将返回这个a的列表。
我们需要的另一个基础构件是 \w 符号。它匹配任何字母数字字符,但不匹配符号。1、K和i 只是 \w 可以匹配的三个例子。
正则表达式可以轻松组合,以允许在搜索中使用更复杂的模式。在将其应用于电子邮件场景之前,让我们探索一下如果将 \w 与加号(+)结合可以搜索哪些模式。
\w 匹配任何字母数字字符,而加号(+)匹配其前面字符的任意多次出现。这意味着 \w+ 的组合匹配任意长度的字母数字字符串。\w 为此正则表达式匹配的字母数字字符提供了灵活性,而加号(+)为其匹配的字符串长度提供了灵活性。
字符串 1、9、2、ABC、123 和 security 只是与 \w+ 匹配的三个可能字符串。
现在,让我们应用这些知识从日志中提取电子邮件地址。电子邮件地址由被某些符号(如@符号和句点.)分隔的文本组成。让我们学习如何将其表示为正则表达式。
首先,考虑典型电子邮件地址的格式,例如 user1@email.com。电子邮件地址的第一段包含字母数字字符,并且字母数字字符的数量可能长度不一。我们可以使用正则表达式 \w+ 来匹配此部分,以匹配任意长度的字母数字字符串。
电子邮件地址中的下一段是@符号。这段始终存在。我们将在正则表达式中直接输入这个符号。这对于确保Python将电子邮件地址与其他字符串区分开来至关重要。
@符号之后是域名。与第一段一样,这部分因电子邮件地址而异,但它始终包含字母数字字符,因此我们可以再次使用 \w+ 来适应这种变化。
接下来,就像@符号一样,句点.始终是电子邮件地址的一部分。但与正则表达式中的@符号不同,句点.具有特殊含义。因此,我们需要在这里使用 \.。当我们在它前面加上反斜杠时,我们让Python知道我们不打算将其用作运算符,并且我们的模式应在此位置包含一个句点。
对于最后一段,我们也可以使用 \w+。电子邮件地址的最后部分通常是.com,但也可能是其他字符串如.net。
当我们把这些部分组合在一起时,就得到了用于在日志中查找电子邮件地址的正则表达式:\w+@\w+\.\w+。这个模式将匹配所有电子邮件地址,并排除字符串中的所有其他内容。这是因为我们在电子邮件地址结构中出现的位置包含了@符号和句点。
让我们在Python中实现它。我们将使用正则表达式从字符串中提取电子邮件地址。当re模块被导入Python后,就可以使用正则表达式。因此,我们从这一步开始。稍后,我们将学习如何导入和打开文件(如日志)。但现在,我们已将日志存储为一个名为email_log的字符串变量。由于这是一个多行字符串,我们使用三组引号而不是一组。
接下来,我们将对正则表达式应用re模块中的findall函数。re.findall返回与正则表达式匹配的列表。
让我们将其与我们之前为电子邮件地址创建的正则表达式一起使用。第一个参数是我们想要匹配的模式。请注意,我们将其放在引号中。第二个参数指示在哪里搜索该模式。在本例中,我们正在搜索email_log变量中包含的字符串。
当我们运行此代码时,我们得到了字符串中所有电子邮件的列表。想象一下将其应用于具有数千条条目的日志。非常有用,对吧?这只是对正则表达式强大功能的介绍。还有更多符号可以使用。我鼓励你自行探索正则表达式并了解更多。


在本节课中,我们一起学习了正则表达式的基础知识,包括加号(+)和\w等符号的含义,以及如何将它们组合起来构建复杂的搜索模式。我们特别实践了如何构建一个匹配电子邮件地址结构的正则表达式模式(\w+@\w+\.\w+),并使用Python的re.findall()函数从文本中提取所有匹配项。这为自动化处理日志文件等网络安全任务提供了强大的工具。
Python自动化网络安全任务:第七课:总结

在本节课中,我们将回顾并总结第七课所涵盖的核心概念与技能。
我们共同完成了许多内容。现在花点时间快速回顾一下我们学习的所有新概念。
字符串与列表操作
我们首先聚焦于字符串和列表的处理。我们学习了专门用于这些数据类型的方法,例如:
- 字符串方法:如
.upper(),.lower(),.split()。 - 列表方法:如
.append(),.remove(),.index()。
同时,我们也学习了如何使用索引来定位和提取所需的信息,例如通过 my_string[0] 或 my_list[2:5] 来访问特定元素或子序列。
算法编写
接下来,我们重点学习了编写算法。我们编写了一个简单的算法,用于从IP地址列表中提取网络ID。这通常涉及字符串分割和切片操作,例如:
ip_address = "192.168.1.100"
network_id = ".".join(ip_address.split(".")[:3]) # 结果为 "192.168.1"
正则表达式
最后,我们学习了使用正则表达式。正则表达式允许你搜索特定的文本模式,这为在日志文件和其他文件中定位所需信息提供了更强大的方法。例如,模式 \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} 可用于匹配IP地址。

这些概念具有一定复杂性。欢迎你随时重新观看相关视频以加深理解。
掌握这些概念后,你在处理数据和编写安全专业人员所需的算法方面迈出了一大步。
在本课程的后续部分,你将获得更多关于Python及其在安全分析中应用的实践机会。
总结

本节课中,我们一起学习了Python中处理字符串和列表的核心方法、编写简单算法的基础,以及使用正则表达式进行模式匹配的强大功能。这些技能是自动化网络安全任务的重要基石。
030:欢迎来到第四周 🚀

在本节课中,我们将要学习如何将Python应用于实际的网络安全分析工作中。我们将重点探讨如何处理和分析安全日志文件,并学习如何调试代码以解决常见的错误。
我们已经一起学习了许多关于Python的知识,并且还有更多内容等待探索。在本节中,我们将探索像您这样的安全分析师如何将Python付诸实践。
作为一名安全分析师,您很可能会处理记录各种系统活动信息的安全日志。这些日志通常非常庞大,难以快速解读。但Python可以轻松地自动化这些任务,使工作变得更加高效。
因此,首先我们将重点学习在Python中如何打开和读取文件,这包括日志文件。之后,我们将探索如何解析文件。这意味着您将能够以提供您所关注的安全相关信息的方式来处理文件。
最后,编写代码的一部分工作是调试代码。能够解读错误信息以使您的代码正常运行,这一点非常重要。我们将涵盖常见的Python错误类型及其解决方法。
总的来说,在完成本节学习后,您将对Python以及作为一名安全分析师如何运用它有更深入的理解。我迫不及待地想与您一同学习。😊

本节课中我们一起学习了第四周的课程概述,明确了我们将要探索如何利用Python处理安全日志、解析文件以及调试代码。这些技能对于高效地进行网络安全分析至关重要。
031:用Python自动执行网络安全任务


在本节课中,我们将学习如何利用Python自动化常见的网络安全任务。自动化是安全领域的关键,它能帮助安全分析师高效地监控系统、检测异常活动并实施安全策略。我们将通过三个具体的应用场景,来理解Python在自动化安全控制中的作用。
🛡️ 自动化在网络安全中的重要性
自动化是安全专业的一个核心关注点。例如,逐一监控每次尝试访问系统的行为非常困难。因此,自动化实施的安全控制措施有助于将恶意行为者挡在系统之外。同时,自动化检测初始攻击活动也极为有用。Python是实现自动化的绝佳工具。
接下来,让我们探索三个具体示例。
🏥 示例一:实施数据库登录超时策略
想象你是一家医疗公司的安全分析师,该公司将机密病人记录存储在数据库服务器中。公司希望实施额外的控制措施来保护这些信息,以增强记录的安全性。
你决定实施一个超时策略:如果用户花费超过三分钟登录数据库,则锁定该用户。这是因为,如果用户花费时间过长,可能是在猜测密码。
以下是实现此策略的一种Python思路:
# 伪代码示例:跟踪用户登录时间
import time
def track_login_time(username):
start_time = time.time()
# 等待用户输入密码...
# 验证密码...
elapsed_time = time.time() - start_time
if elapsed_time > 180: # 超过3分钟(180秒)
lock_user_account(username)
你可以使用Python来识别用户何时输入了用户名,并开始跟踪时间,直到该用户输入正确密码为止。
上一节我们介绍了如何用Python实施登录超时策略。接下来,让我们看看另一个不同的应用场景。
⚖️ 示例二:分析与标记异常登录行为
这次,想象你是一家律师事务所的安全分析师。最近持续发生一些安全攻击,威胁行为者入侵员工账户并试图窃取客户信息,然后威胁要恶意使用这些信息。因此,安全团队正在努力解决所有允许攻击者侵入公司数据库的安全漏洞。
你个人负责通过检查用户的登录时间戳、IP地址和登录地点来跟踪所有用户登录。
以下是需要标记账户的几种情况:
- 如果用户在清晨时段登录,应标记其账户。
- 如果用户从两个既定工作区域以外的地点登录,必须标记其账户。
- 如果用户同时从两个不同的IP地址登录,必须标记其账户。
Python可以帮助你跟踪和分析所有这些不同的登录信息。
我们了解了如何用Python分析登录行为。现在,让我们考虑最后一个示例,它涉及监控失败的登录尝试。
🚨 示例三:监控失败登录以检测可疑活动
想象你是一家大型组织的安全分析师。最近,该组织加强了安全措施,以确保所有面向客户的应用程序得到更好保护。由于访问这些应用程序需要密码,他们希望监控所有密码登录尝试,以发现可疑活动。


可疑活动的一个迹象是在短时间内出现多次失败的登录尝试。如果用户在最近30分钟内登录失败超过三次,你需要标记该用户。
在Python中实现此功能的一种方法是,解析一个包含所有用户对每台机器的登录尝试的静态TXT日志文件。
以下是Python可以执行的操作:
- 解析日志文件:从TXT文件中提取信息。
- 结构化数据:整理信息,包括用户名、IP地址、时间戳和登录状态。
- 应用条件判断:使用条件语句(如
if)来确定是否需要标记用户。
# 伪代码示例:分析登录日志
def analyze_login_log(log_file_path):
flagged_users = []
# 读取并解析日志文件...
# 对每个用户,检查过去30分钟内的失败次数...
for user in user_login_attempts:
if count_failed_attempts(user, last_30_min) > 3:
flagged_users.append(user)
return flagged_users
📝 总结
本节课中,我们一起学习了Python在自动化网络安全任务中的应用。我们通过三个具体示例——实施登录超时策略、分析异常登录行为以及监控失败登录尝试——看到了Python如何帮助安全分析师自动化日常监控、检测和响应流程。这些只是安全分析师在日常工作中应用Python的少数几个例子。希望你能和我一样,对为安全问题创建自动化解决方案感到兴奋。
032:持续学习与Python应用

概述
在本节课中,我们将跟随谷歌高级安全工程师克兰西的分享,了解Python在网络安全领域的实际应用价值,以及如何通过持续学习和实践来掌握这门强大的编程语言。课程将重点阐述Python的特点、学习路径以及给初学者的建议。
我的名字是克兰西,我是一名高级安全工程师。
我在谷歌的团队致力于持续保护谷歌的敏感信息和客户数据。
我的日常工作每天都不相同,这让我有机会运用不同的技能和知识体系,没有哪两天是完全一样的。
严格来说,我并非工程师或软件工程师出身;我实际上曾是会计专业。亲身经历任何类型的网络安全攻击,无疑会让你从对立面的角度获得深刻见解。
你能看到这如何影响用户,如何影响遭受攻击的人们。
如果我刚开始职业生涯时就了解网络安全领域究竟有多么广阔,那将能让我更早地开始探索。Python是我在谷歌的职位上经常使用的一种开发语言。
关于Python,我最喜欢的一点是它的强大能力。你可以用它创建功能强大的脚本,并将其应用于日常工作中。
当我最初学习Python时,最棘手的部分是学会如何以“Pythonic”的方式表达逻辑。
我利用了各种在线资源、书籍,并着手进行一些副业项目。Python最大的优点之一是它是一门应用非常广泛的语言,你可以根据自身技能水平,在网上找到海量的学习资源。
Python以及任何其他开发语言都在不断演进。
持续承担项目,持续拓展你的知识边界,你就能持续成长。
我能给刚开始学习Python的人的建议是:让它变得有趣。我认为,一旦你发现学习一门语言是有趣的,你就能更投入地学习。首先,为网络安全建立一个良好的知识基础。
在起步阶段,让自己涉猎广泛一些,变得全面一些。然后,你可以从那里出发,深入钻研你感兴趣的主题。
刚开始时可能会非常艰难,你会感觉像是在攀登一座大山。
请坚持下去,持续学习,这最终将是一段非常有价值的经历。
总结

本节课中,我们一起学习了高级安全工程师克兰西的经验分享。我们了解到Python因其强大和灵活的特性,成为网络安全自动化任务中的重要工具。掌握Python的关键在于以“Pythonic”的思维方式解决问题,并充分利用丰富的在线资源进行学习。对于初学者,建立广泛的网络安全知识基础,并通过有趣的项目保持学习动力至关重要。网络安全和编程语言都在不断发展,因此保持持续学习和实践是职业成长的核心。尽管起步可能充满挑战,但坚持不懈终将带来丰厚的回报。
033:用Python访问文本文件

在本节课中,我们将学习如何使用Python读取文本文件。这对于网络安全专业人员处理日志文件等任务至关重要。我们将从基础开始,学习如何打开文件、读取内容并将其存储为字符串,为后续处理安全日志打下基础。
打开并读取文本文件
网络安全专业人员经常需要审查日志文件。这些文件可能包含成千上万的条目,因此自动化此过程会很有帮助。这正是Python可以发挥作用的地方。我们将从一个只包含几个单词的简单文本文件开始,学习如何在Python中读取它并将其存储为字符串。
我们只需要文本文件、其位置以及正确的Python关键字。以下是实现此目标的核心步骤。
使用 with 语句
我们将从输入一个 with 语句开始。关键字 with 用于处理错误和管理外部资源。当使用 with 时,Python知道自动释放那些在程序运行结束前会占用系统资源的资源。在文件处理中,它常用于在读取文件后自动关闭文件。
要打开并读取文件,我们编写一个以关键字 with 开头的语句。
open 函数
open 是Python中用于打开文件的函数。其基本语法如下:
open(file, mode)
- 第一个参数:是您计算机上文本文件的名称,或其在互联网上的链接。根据Python环境,您可能还需要包含此文件的路径。请记住在文件名中包含扩展名,例如
.txt。 - 第二个参数:此参数告诉Python我们想对文件做什么操作。在我们的例子中,我们想读取文件,因此我们在引号中使用字母
"r"。如果我们想写入文件,我们会将此"r"替换为"w",但这里我们专注于读取。
文件变量与代码块
file 是一个变量,只要我们在 with 语句内部,它就包含文件信息。与其他类型的语句类似,我们以冒号结束 with 语句。冒号后的代码将告诉Python如何处理文件的内容。
实践操作:读取文件内容
现在,让我们进入Python并使用我们学到的知识。我们准备在Python中打开一个文本文件。
首先,我们输入 with 语句。接下来,我们将使用Python内置的 read 方法。read 方法将文件内容转换为字符串。
让我们回到我们的 with 语句。类似于 for 循环,with 语句在下一行开始缩进。这告诉Python此代码正在 with 语句内部执行。
在语句内部,我们将使用 read 函数将文件转换为字符串,并将其存储在一个新变量中。这个新变量可以在 with 语句外部使用。
因此,让我们通过取消缩进来退出 with 语句,并打印该变量。完美,文本中的字符串被打印出来了。
总结与展望

本节课中,我们一起学习了如何使用Python的 with 语句和 open 函数安全地打开并读取文本文件,以及如何使用 read 方法将文件内容转换为字符串。这是自动化处理文件(如安全日志)的第一步。
接下来,我们将讨论解析文件,以便我们将来能够处理安全日志。
034:用Python解析文本文件

在本节课中,我们将学习如何解析文本文件。解析是将数据转换为更易读格式的过程。我们将结合之前学到的列表和字符串知识,并学习一个新的字符串方法——split方法,来为文本文件赋予结构,从而更轻松地分析数据。
上一节我们介绍了如何将文本文件导入Python。本节中,我们来看看如何进一步处理这些文本,即解析它们。
解析与split方法
解析是将数据转换为更易读格式的过程。为了实现解析,我们需要使用字符串的split方法。这个方法可以将一个字符串转换成列表。
split方法通过基于指定字符分隔字符串来工作。如果不传递任何参数,则每次遇到空白字符(如空格、换行符)时,它就会分隔字符串。
以下是split方法的基本用法:
# 示例:使用split方法
text = "We are learning about parsing."
word_list = text.split()
print(word_list)
# 输出: ['We', 'are', 'learning', 'about', 'parsing.']
我们使用split方法将字符串分割成更小的片段,这比分析一大块文本要容易得多。
解析安全日志示例
在本视频的示例中,我们将处理一个安全日志文件,其中每一行代表一个新的数据点。我们的目标是将文本基于换行符进行分隔。
Python将换行符视为一种空白字符,因此我们可以直接使用不带参数的split方法。
我们将从上一节的代码开始。以下是打开文件并将其内容读入字符串的代码:
# 从上一节延续的代码:打开并读取文件
with open('update_log.txt', 'r') as file:
log_data = file.read()
现在,让我们使用split方法将这个字符串分割成列表,然后打印输出:
# 使用split方法解析字符串
username_list = log_data.split()
print(username_list)
运行这段代码后,Python会输出一个用户名列表,而不是一个长长的字符串。
如果我们想保存这个列表以供后续使用,需要将其赋值给一个变量。例如,我们可以将这个变量命名为usernames:
# 将解析后的列表保存到变量中
usernames = log_data.split()
print(usernames)

现在,这个usernames列表就可以在其他代码中重复使用了。
总结
本节课中我们一起学习了Python中解析文本文件的基础知识。我们了解到,解析是将数据(如文本文件内容)转换为更结构化、更易分析格式的过程。核心是通过字符串的split()方法来实现这一转换,该方法能将字符串基于分隔符(默认为空白字符)分割成一个列表。

你已经掌握了将文本文件内容解析为结构化数据列表的基本技能。在接下来的视频中,我们将探索更多技术,以帮助更深入地处理和分析Python中的数据。
035:用Python开发解析算法 🐍

在本节课中,我们将综合运用之前学到的知识,学习如何导入文件、解析数据,并实现一个简单的算法来检测可疑的登录尝试。我们将创建一个程序,在每次有新用户登录时运行,检查该用户是否有三次或更多次失败的登录尝试。
概述
我们将处理一个存储失败登录尝试的日志文件。程序的核心任务是:读取日志文件,统计特定用户名的出现次数,如果次数达到或超过三次,则发出警报。我们将从文件导入开始,逐步构建一个完整的解析和检测算法。
导入与解析日志文件
首先,我们需要导入包含失败登录尝试的日志文件。该文件是TXT格式,每行包含一个用户名,每个用户名代表一次失败的登录尝试。
以下是导入文件并将其内容存储到变量中的代码:
with open('login_attempts.txt', 'r') as file:
usernames = file.read().splitlines()
我们使用 with open 语句打开文件,'r' 表示读取模式。file.read().splitlines() 方法读取整个文件内容,并按行分割,将每一行作为一个元素存入名为 usernames 的列表中。
为了验证导入是否成功,我们可以打印 usernames 变量的内容:
print(usernames)
运行代码后,如果输出显示一个用户名列表,则说明文件已成功导入并解析。现在,usernames 列表已准备就绪,可供我们的算法使用。
设计计数算法策略
上一节我们成功导入了数据,本节中我们来看看如何统计列表中特定用户名的出现次数。我们以列表中的前八个元素为例进行说明。
假设我们注意到用户名 “eraab” 在列表中出现了两次。我们需要设计一种方法,让Python能够自动进行这种计数。
我们将实现一个 for 循环来遍历列表中的每个元素。同时,我们定义一个计数器变量,初始值设为0。
以下是算法的逻辑步骤:
- 遍历列表中的每个用户名。
- 对于每个用户名,检查它是否等于我们正在查找的目标用户名(例如 “eraab”)。
- 如果相等,则将计数器加1。
- 如果不相等,则计数器保持不变。
遍历完整个列表后,计数器的值就是目标用户名出现的总次数。
在Python中实现算法
现在我们已经明确了解决方案,接下来看看如何在Python代码中实现它。解决这个问题将涉及一个 for 循环、一个计数器变量和一个 if 语句。
让我们回到代码编辑器,创建一个函数来统计用户的失败登录尝试次数。
首先,定义我们的函数:
def login_check(login_list, current_user):
这个函数名为 login_check,它接受两个参数:
login_list:用于传入失败登录尝试的列表。current_user:用于传入当前正在尝试登录的用户名。
在函数内部,我们首先定义计数器变量并将其初始值设为0:
counter = 0
接下来,启动一个 for 循环。我们将使用 i 作为循环变量,遍历 login_list:
for i in login_list:
在 for 循环内部,我们使用一个 if 语句。该语句检查循环变量 i(即当前遍历到的用户名)是否等于我们正在搜索的 current_user:
if i == current_user:
如果这个条件为真,我们希望对计数器加1:
counter = counter + 1
至此,计数逻辑已完成。现在,我们只需要最后的 if-else 语句来根据计数结果打印警报。
如果计数器累加到3或更多,我们需要告知用户其账户已被锁定。我们也会为可以登录的用户编写一条 else 语句:
if counter >= 3:
print("Account locked. Too many login attempts.")
else:
print("You can log in.")
我们的算法现在已经完成。
测试算法功能
让我们用一个示例用户名来测试新创建的函数。我们可以从列表中选取几个用户名进行尝试。
首先,使用列表中的第一个用户名进行测试:
login_check(usernames, "elarson")
运行代码。根据输出,如果显示 “You can log in.”,则说明该用户的失败登录尝试少于三次。
现在,让我们测试之前提到的用户 “eraab”。在列表的前八个名字中,它出现了两次。你认为他能够登录吗?
运行测试:

login_check(usernames, "eraab")
如果得到 “Account locked.” 的消息,则意味着该用户有三次或更多次失败的登录尝试。优秀!你已经开发了第一个涉及日志分析的安全算法。
随着技能的增长,你将学习如何使这个算法更加高效,但目前的解决方案运行良好。
总结
在本节课中,我们一起学习了如何将列表操作、算法开发和文件解析等知识综合运用。我们通过构建一个可在安全上下文中应用的算法来实现这一目标。具体来说,我们:
- 导入并解析了包含失败登录尝试的TXT日志文件。
- 设计了一个使用
for循环和计数器来统计用户名出现次数的策略。 - 在Python中实现了一个名为
login_check的函数,该函数能够分析登录列表并针对可疑尝试发出警报。 - 通过实际用户名测试了算法的功能。

这个程序是自动化安全任务的一个基础而实用的例子。
036:调试策略 🐛

在本节课中,我们将学习如何识别和修复Python代码中的错误。作为一名安全分析师,阅读或编写代码是常见任务,而让代码正确运行并发挥功能是最大的挑战之一。事实上,修复复杂的代码错误有时比编写代码本身花费的时间一样多,甚至更多。因此,掌握调试技能至关重要。我们已经学习了Python编程基础,现在需要学习如何处理错误。为此,我们将重点讨论代码调试。
调试是指识别和修复代码错误的过程。本视频将探讨一些调试技术。
错误类型
代码错误主要分为三种类型:语法错误、逻辑错误和异常。
语法错误
语法错误涉及对Python语言的无效使用,例如在函数定义后忘记添加冒号。
让我们探索这种错误类型。当我们运行以下代码时,会收到一条指示存在语法错误的消息。根据Python环境,它可能还会显示其他详细信息。我们通常会获得有关错误的信息,例如其位置。
def my_function()
print("Hello")
这些语法错误通常很容易修复,因为你可以精确地找到错误发生的位置。它们类似于纠正电子邮件中的简单语法错误。由于错误消息告诉我们问题出在定义函数的那一行,让我们去那里看看。在这种情况下,我们可以在函数头后添加一个冒号来解决错误。当我们再次运行它时,就不再出现错误消息了。
这只是语法错误的一个例子。其他例子包括:函数调用后省略括号、拼错Python关键字或未正确关闭字符串的引号。
逻辑错误
上一节我们介绍了语法错误,本节中我们来看看逻辑错误。逻辑错误可能不会导致错误消息,而是产生非预期的结果。一个逻辑错误可能很简单,比如在打印语句中写错了文本;也可能涉及更复杂的情况,比如写了一个小于符号而不是小于或等于符号。
这种操作符的改变会排除代码按预期工作所需的一个值。例如,假设你只在问题的优先级小于3(而不是小于或等于3)时才联系响应团队。这意味着所有被归类为优先级3的事件都可能被忽视且无法解决。
以下是诊断难以发现的逻辑错误的策略:
- 使用打印语句:你需要在代码中各处插入打印语句。这些打印语句应描述代码中的位置,例如
print("第20行")或print("条件语句内第55行")。其思路是使用这些打印语句来识别代码的哪些部分运行正常。当一个打印语句没有按预期打印时,这有助于你识别出有问题的代码部分。 - 使用调试器:另一个识别逻辑错误的选项是使用调试器。调试器允许你在代码中插入断点。断点允许你将代码分段,并一次只运行一部分。就像使用打印语句一样,独立运行这些部分有助于隔离代码中的问题。
异常
我们讨论了语法和逻辑错误,现在来关注最后一种错误类型:异常。异常发生在程序不知道如何执行代码时,即使语法没有问题。异常的发生有多种原因。
例如,当出现数学上不可能的情况时会发生异常,比如要求代码除以0。当你要求Python访问不存在的索引值时,或者当Python无法识别变量或函数名时,也可能发生异常。使用不正确的数据类型时也可能发生异常。
让我们演示一个异常。假设你有一个名为 my_string 的变量,其中包含单词 "security"。由于这个字符串有8个字符,我们可以成功打印任何小于8的索引。索引0包含 'S',索引1包含 'E',索引2包含 'C'。
my_string = "security"
print(my_string[0]) # 输出: s
print(my_string[1]) # 输出: e
print(my_string[2]) # 输出: c
但是,如果你尝试访问索引100处的字符,就会得到一个错误。
print(my_string[100]) # 这将引发异常
让我们运行这些代码,看看会发生什么。在成功打印前三个语句后,我们得到一个错误消息:IndexError: string index out of range。
对于异常错误,你也可以利用调试器和打印语句来找出错误的潜在来源。

总结

在本节课中,我们一起学习了Python编程中三种主要的错误类型及其调试策略。语法错误涉及无效的Python语法,通常易于定位和修复。逻辑错误不会中断程序,但会导致非预期结果,可以通过插入打印语句或使用调试器来诊断。异常发生在运行时,即使语法正确,程序也无法执行某些操作。在Python中工作时,遇到错误和异常是预料之中的事。重要的是要知道如何处理它们。希望本视频提供了关于调试代码的一些有价值的见解,这将有助于确保你编写的代码功能正常。
037:从错误中学习


在本节课中,我们将跟随软件工程师马特的分享,学习如何将编程中的错误视为宝贵的学习机会,并了解在网络安全工作中处理复杂问题的思维方式。
我叫马特,是一名从事网络安全工作的软件工程师。高中时,我真正想做的是音乐,我曾是一名音乐家。因此,我去了音乐学校学习爵士长号。在这个过程中,我逐渐意识到,没有哪个明智的乐队领队会看着一个团队,然后认为我们需要一个长号手来让事情变得更好。
我从小看着《黑客帝国》这样的电影长大。虽然这与网络安全工作的实际情况不太一样,但它确实能带来一些启发。当你深入挖掘工作的具体细节,再退一步看全局时,你就像那个戴着谷歌眼镜的黑客。
当我刚开始写代码时,我会把编码错误看作是我做得不好的标志。但随着年龄增长,我变得更加成熟,意识到每个人都会犯编码错误。我认识的最优秀的软件工程师写的代码也会有错误。错误代表了一个你可以退一步思考的时刻,去问自己“我做错了什么”。这是一个学习的机会。

现在,我把这些错误看作是审视我不理解的问题、并深入探究以扩展计算机科学知识的时刻,而这正是我工作的全部。所以,我把这看作一个学习过程,并且它还有点乐趣。
接下来,我将分享一个我在谷歌工作时遇到的非常棘手的编码错误案例。
以下是我在谷歌遇到的一个非常棘手的编码错误案例,它涉及“指纹识别”技术。
当我们发现一个漏洞时,如果我们后来发现了相同的漏洞,我们不希望有两个重复的漏洞记录。我们不想两次提醒同一个人去修复同一个问题。因此,我们采用了一种称为“指纹识别”的技术。我们为每个漏洞分配一个特定的“指纹”。如果我们发现另一个具有相同指纹的漏洞,我们不会将它们分开存储或处理,因为它们本质上是同一个漏洞。
我遇到了这样的错误:某些漏洞没有按照我预期的方式进行指纹识别。我为此绞尽脑汁了好几个星期,试图弄清楚到底哪里出了问题。但当我最终找到原因时,那种感觉非常、非常满足。就像“哦,原来是这样”。
当你深陷于这种混乱中时,所有的自我怀疑都会涌入脑海。你可能会想:“也许我并没有自己想象的那么擅长这件事。”如果我能回到过去告诉当时的自己,我会说两点:第一,困境不是永无止境的,情况会好转。一旦你解决了问题,那种成就感是无与伦比的。第二,向他人求助是完全没问题的。
如果你正在为某件事而挣扎,我总是提倡寻求帮助。大多数人都会非常乐意帮助你解决问题,尤其是当它涉及一个复杂的问题时。
我非常高兴自己最终进入了网络安全领域。网络安全正处在一个重要的时代。人们开始意识到他们向世界投放的数据量,并开始关心数据安全。因此,每天都有新事物出现,每天都有让我感到兴奋的事情可做。是的,投身其中吧。网络安全是未来的方向。
在本节课中,我们一起学习了如何将编程错误视为学习和成长的机会,了解了网络安全中“指纹识别”的概念,并认识到在遇到难题时寻求帮助的重要性。记住,错误不是终点,而是通往精通的阶梯。
038:应用调试策略 🐛

在本节课中,我们将学习如何应用系统性的调试策略来解决Python代码中的问题。我们将通过一个实际案例,逐步识别并修复语法错误、异常和逻辑错误,最终确保代码按预期运行。
假设我们的同事需要帮助让他们的代码正常工作。我们主动提出调试他们的代码,以确保其平稳运行。
首先,我们需要了解代码的用途。在本例中,代码的目的是解析日志文件中的单行数据并返回它。我们使用的日志文件用于跟踪软件应用程序的潜在问题。日志中的每一行都包含HTTP响应状态码、日期、时间和应用程序名称。
编写此代码时,我们的同事考虑了是否所有状态码都需要解析。由于状态码200表示成功事件,他们得出结论:不应解析包含此状态码的行。相反,Python应返回一条消息,指示无需解析。
识别错误
为了开始调试过程,我们首先运行代码以识别出现了哪些错误。
我们的第一个错误是语法错误。错误信息还告诉我们,语法错误发生在定义函数的那一行。
让我们滚动到代码的那一部分。你可能还记得,函数定义行应以冒号结尾。我们继续在代码中添加冒号。现在,语法错误应该消失了。让我们再次运行代码。
处理异常
现在我们的语法错误消失了,这是个好消息,但我们遇到了另一个错误:NameError。
NameError实际上是一种异常类型,意味着我们编写的语法是有效的,但Python无法处理该语句。根据错误信息,解释器在将变量 application name 添加到 parse_line_list 时无法理解它。
让我们检查代码的那一部分。这个错误意味着我们没有正确分配变量名。现在,让我们回到它首次被赋值的地方,看看发生了什么。
我们发现这个变量拼写错误。application name 应该是两个单词,而不是一个。让我们纠正拼写。修复后,它应该可以工作了。所以,让我们运行代码。
检查逻辑
太好了,我们修复了一个错误和一个异常。并且不再有任何错误消息。但这并不意味着我们的调试工作已经完成。我们需要通过检查输出来确保程序的逻辑按预期工作。
我们的输出是一个解析后的列表。在大多数情况下,这正是我们想要的。但你可能还记得,如果状态码是200,我们的代码不应该解析该行。相反,它应该打印一条消息,说明无需解析。
然而,当我们用状态码200调用它时,并没有显示这条消息。这表明存在一个逻辑错误。
定位逻辑错误
让我们回到用于处理状态码200的条件语句并进行调查。为了找到问题的根源,我们添加一些 print 语句。
在我们的 print 语句中,我们包含了行号和位置描述。
- 我们将在包含
return parse_list的代码行之前添加一个print语句。 - 我们将在检查200状态码的
if语句上方添加另一个print语句,以确定程序是否执行到了该if语句。 - 我们将在
if语句内部再添加一个print语句,以确定程序是否进入了该分支。
现在,让我们运行代码并查看打印出的内容。
只有第一个 print 语句打印了内容。之后的另外两个 print 语句没有打印任何东西。这意味着程序甚至没有进入那个 if 语句。
问题发生在返回 parse_line 变量的那一行之前的某个地方。
修复逻辑错误
让我们进一步调查。当Python遇到第一个 return 语句(即返回 parse_list 的那一行)时,它会退出函数。换句话说,它在检查状态码值是否为200之前就返回了列表。
为了修复这个问题,我们必须将检查状态码的 if 语句移到 return parse_line 之前的某个位置。
首先,我们删除之前添加的 print 语句。这使程序更高效,因为它不会运行任何不必要的代码行。
现在,让我们移动 if 语句。我们将其放在从行中解析状态码的代码行之后。
让我们运行代码,确认这修复了我们的问题。是的,它打印了“successful event. No parsing needed.”。

总结 🎯
在本节课中,我们一起学习了应用系统性的调试策略。我们首先通过运行代码识别了语法错误并进行了修复。接着,我们处理了NameError异常,通过检查变量赋值纠正了拼写错误。最后,我们深入排查了逻辑错误,通过添加 print 语句定位问题根源,并通过调整代码执行顺序(将条件判断移到 return 语句之前)成功修复了它。这个过程展示了调试代码的基本步骤:识别错误类型、定位问题代码、分析原因并实施修复。
039:总结

在本节课中,我们学习了几个新的主题,这些主题将帮助你在安全专业实践中应用Python。
上一节我们介绍了Python的基础知识,本节中我们来看看如何将这些知识应用于处理安全工作中的具体任务。
📂 打开与读取文件
首先,我们探讨了如何在Python中打开和读取文件。安全分析师需要处理大量的日志文件,因此掌握这项技能至关重要。以下是读取文件的基本代码示例:
with open('logfile.txt', 'r') as file:
content = file.read()
🔍 解析文件
接下来,我们讲解了如何解析文件。日志文件通常非常冗长。因此,解析这些文件的结构,使其更易读,有助于你自动化任务并获取所需信息。例如,我们可以逐行读取并筛选特定信息:
with open('logfile.txt', 'r') as file:
for line in file:
if "ERROR" in line:
print(line)

🐛 调试代码
最后,我们重点学习了如何调试代码。掌握调试技巧可以为你节省大量时间,尤其是在代码复杂度增加时。使用 print 语句或调试器是常见的调试方法。
def calculate_sum(a, b):
# 调试:打印输入值
print(f"a: {a}, b: {b}")
return a + b

本节课中我们一起学习了如何用Python处理安全领域的实际问题,包括文件操作、数据解析和代码调试。通过掌握这些技能,你将能够更高效地应对安全挑战。
040:课程总结

在本节课中,我们将回顾并总结整个课程的核心内容。我们一起学习了Python编程的基础知识及其在网络安全领域的应用。
课程回顾
上一节我们探讨了Python在实践中的应用,本节中我们来对整个课程进行总结。
首先,我们学习了Python的基础编程概念。
以下是本课程涵盖的核心主题:
- 变量、数据类型、条件语句和循环语句:这些是编程的基石。例如,变量赋值
name = "Alice",条件判断if x > 0:,以及循环for item in list:。 - 编写高效的Python代码:我们学习了如何通过函数来重用代码,提高效率。这包括使用内置函数和创建自定义函数,例如
def greet_user(name):。 - 模块和库:我们了解到,通过导入模块(如
import re),可以使用其中预打包的函数和变量,从而简化工作。 - 代码可读性:我们强调了编写清晰、易读代码的重要性。
接下来,我们的重点是处理字符串和列表。
以下是相关的关键技能:
- 字符串和列表方法:我们学习了多种可应用于这些数据类型的方法,例如字符串的
.upper()或列表的.append()。 - 索引和切片:我们了解了如何通过索引访问元素,以及如何使用切片语法(如
my_string[0:5]或my_list[1:])来获取子集。 - 编写简单算法:我们综合运用这些知识来编写基础的算法。
- 正则表达式:我们探索了如何使用正则表达式(通过
re模块)在字符串中查找复杂模式。
最后,我们将Python投入实践。
以下是本部分的核心实践技能:

- 文件的打开、读取和解析:我们学习了如何使用
open()、.read()、.readlines()等方法来处理文件。掌握这些技能后,你就能处理在安全环境中遇到的各种日志文件。 - 调试代码:我们学习了调试的基本方法,这是所有程序员都必须掌握的重要技能。
总结与鼓励
本节课中,我们一起学习了Python编程从基础到实践的完整路径。你探索了对安全领域非常有用的编程语言,这值得祝贺。
你在本课程中学到了很多关于Python的知识,做得非常出色。我希望不久后,你能和我一起在网络安全专业中应用Python。
同时,我鼓励你多加练习,并随时可以重新观看这些视频。你越是深入研究这些概念,它们就会变得越容易。
再次感谢你与我一同探索Python。
041:课程介绍


概述
在本节课中,我们将要学习如何将Python编程语言作为网络安全工具箱的一部分,并了解它如何帮助自动化常见的网络安全任务。
对网络安全专业人员的需求达到了前所未有的高度。全球各地的组织都需要具备专业知识和技能的人员来保护其系统免受攻击者侵害。随着威胁数量的不断上升,安全专业人员通常需要执行多种多样的任务。
正因如此,我们将在安全工具箱中引入另一个工具。这个工具可以简化许多常见的安全任务。它不仅被安全专业人员使用,也被工程师和数据科学家广泛采用。这个工具就是Python。
大家好。祝贺你们在安全学习的道路上迈出了新的一步。我叫Anhill,是谷歌的一名安全工程师。我很高兴能在这门课程中与大家一同学习。
课程背景与目标
如果你一直在按顺序学习,那么你已经应用了安全专业人员在检测、分析和响应过程中使用的特定工具。你也学会了如何通过Linux和SQL与计算机进行交互。
现在,我们将重点学习如何使用Python编程来完成一些常见的安全任务。当你考虑职业生涯的下一步时,你可能会发现Python技能将在你的日常工作中提供很大帮助。
这门课程旨在从基础开始学习Python。然后,你将逐步在这些基础上进行构建,并将所学知识应用到与安全相关的实例中进行实践操作。
幸运的是,Python以其可读性著称,并且就像所有语言一样,通过练习会变得越来越容易。很快,你可能就会在你的安全职业生涯中使用Python。Python可以自动化文件解析等重要任务的手动操作。
讲师经验分享
Python在我的谷歌职业生涯中给了我很大帮助。我所在的团队负责保护谷歌的基础设施,这包括员工使用的所有设备,从笔记本电脑、台式机到网络和云资源。我们通过设计安全解决方案和自动化工作中可重复的部分来实现这一目标。
我喜欢Python的一点是它具有跨平台支持,并且安全社区的成员已经开发了许多使用Python的工具。这使我能够轻松找到所需的工具,并在遇到阻碍时获得支持,从而完成我的专业和个人项目。
我希望这门课程能对你有所帮助。
课程内容预览
让我们来了解一下我们将要涵盖的内容。
首先,你将学习Python的基本编程概念。你将了解为什么Python被全球的安全专业人员所采纳。你还将开发并运行你的第一个程序。
接下来,我们将专注于编写高效的Python代码。我们将讨论有助于提高工作效率的概念。
我们的下一个主要主题是关于处理字符串和列表。这些内容将与你将在安全环境中遇到的大量数据密切相关。
最后,你将以探索Python的实际应用来结束本课程。你将学习如何打开和解析文件,以及如何调试代码。

总结

本节课中,我们一起学习了Python对于网络安全分析师来说无疑是一项非常有用的技能。让我们开始学习吧。
042:Angela的个人职业旅程 🛤️

在本节课中,我们将跟随谷歌安全工程师Angela的分享,了解她如何从童年时期的好奇心出发,一步步成长为一名网络安全专家。她的职业旅程强调了好奇心、持续学习和适应能力在技术领域,尤其是网络安全领域中的重要性。
我的名字是Angela,我是谷歌的一名安全工程师。
我人生中的许多事情将我引向了安全领域。
其中之一无疑是我成长过程中的好奇心。
我的父母是会计师,所以他们有袖珍计算器、自动铅笔和钢笔。
我总是把它们拆开,取出零件,试图弄清楚它们的工作原理。
这让我对广义上的技术产生了兴趣。
同样的概念再次适用。
就是试图弄清楚事物如何运作,并拆解它们。
这基本上就是安全领域试图做的事情:拆解事物,以弄清楚是否有人能在你之前破坏它们。
我最初是一名网络工程师。
这份工作是为不同的公司设置防火墙、交换机和路由器。
我想加入网络安全领域,主要是因为我被行业内发生的事情所激励,例如“极光行动”——谷歌被外国行为者黑客攻击的事件。
我当时在阅读相关报道。我在想,我希望我能与那些在前线处理这些问题的人一起工作。
当我开始进入网络安全领域,并希望在我的职业生涯中实现一次跨越时,我明确了我想学习什么,以及我需要达到什么水平。
一个例子是通过Python学习自动化。
我参加了在线课程。
我完成了认证,特别是安全领域非常流行的认证。
然后我开始将其中一些方面融入到我当时的工作中。
当我从墨西哥搬到美国工作时,我不得不学会如何保持灵活。
为了推进你的职业生涯,你必须学习新事物。
有时,你甚至需要学习新事物,只是为了保持在原地。
在安全领域,我认为在整个技术领域都是如此,但尤其是在网络安全领域,你必须不断地重塑自己,持续学习事物如何运作,并持续学习你如何能帮助这个行业。
贯穿我一生以及作为网络安全专业人士的职业生涯,一项重要的技能是韧性。
当我第一次搬到美国时,我对韧性有了很多体会。
事情并没有按照我预期的方式发展。
我必须不断尝试新事物。
并抱最好的希望。
这与我们作为安全专业人士的日常工作并无不同。

我们每天都在做这样的事情。
我们必须想办法让事情运转起来。
我们必须想办法让项目按照我们需要的方式运作。
或者我们必须想办法克服一个问题。
网络安全领域需要更多具有不同背景的专业人士。
这意味着不同的经验、看待事物的不同方式、处理和解决问题的不同方法。
这个行业需要更多像你一样的人。
总结
本节课中,我们一起学习了Angela从网络工程师到谷歌安全工程师的职业旅程。她的经历强调了好奇心(拆解事物以理解其原理)和持续学习(例如学习Python自动化)是进入并适应快速发展的网络安全领域的关键。同时,韧性——在面对挑战时不断尝试和适应——是贯穿职业生涯的重要品质。最后,Angela指出网络安全行业需要多元化背景的人才,鼓励拥有不同经验和问题解决方式的人加入。
043:第一周导论

概述
在本节课中,我们将要学习编程语言的基础知识,特别是Python语言的核心组件。我们将从编程的基本概念开始,了解为什么Python在安全分析中被广泛使用,并逐步构建Python编程的基础。
学习一门新的编程语言与学习一门新的人类语言过程相似。例如,与任何人类语言一样,编程语言也由词汇构成。这些词汇被组织在一起,形成代码行。代码行用于与计算机进行通信,类似于一个句子,告诉计算机如何执行一项任务。
在本节中,我们将开始学习与计算机通信所需的语言,同时探索Python的一些关键组成部分。
课程内容
我们将从介绍编程的基础知识开始,首先探讨为什么安全分析师使用Python。
接下来,我们将开始构建Python的基础。我们将讨论数据类型,然后介绍变量。最后,我们将学习可以在Python中使用的特定语句,例如条件语句。条件语句帮助我们将逻辑融入程序中。

我们将学习的第二种语句是迭代语句。迭代语句允许我们多次重复一行代码,而无需重写它。
Python对职业发展的帮助
学习Python帮助我在职业生涯中取得成功,因为使用Python使我能够从重复性任务中解放出时间,转而专注于更具挑战性的任务和问题。
成功应用自动化可以减少我的整体工作量,提高生产力,并降低人为错误的风险。自动化的使用还使我能够专注于需要更多创造力、协作和解决问题的工程任务。

总结
本节课中,我们一起学习了Python编程的入门知识,包括其基本概念、数据类型、变量以及条件语句和迭代语句。这些是构建自动化工具以支持网络安全任务的基础。你准备好开始用Python编程了吗?让我们开始吧。
044:3_02_python-and-cybersecurity


概述 📋
在本节课中,我们将要学习编程在网络安全领域的应用,特别是Python语言如何被用来自动化安全任务。我们将探讨编程的基本概念、Python的特点以及它在安全分析中的具体用途。
编程与网络安全 🔐
安全专业人员会使用多种工具,其中一种就是计算机编程。
编程用于为计算机创建一套特定的指令,以执行任务。
我们可以用一个自动售货机来举例。将自动售货机视为一台向顾客提供食物或饮料的计算机。
为了获得商品,顾客需要向机器投入钱币,然后选择他们想要的商品。
假设顾客向机器提供了5美元。机器会存储这个数值。
同时,顾客进行选择。如果顾客选择了一个价值2美元的糖果棒。机器接收这个输入。
这个输入也被称为一条指令。然后,机器理解指令,输出价值2美元的糖果棒。
并找回3美元的零钱。世界上存在许多种编程语言。
这里我们将重点介绍Python。Python被认为是一种通用语言。
这意味着它可以创建各种不同的程序。
并且不专门针对任何特定问题。
在诸如网络开发和人工智能等领域。
Python通常用于构建网站和进行数据分析。在安全领域。
我们使用Python的主要原因是自动化我们的任务。
自动化是利用技术来减少执行常见和重复性任务所需的人工和手动劳动。
Python通常最适合自动化简短、简单的任务。例如。
处理安全事件的安全分析师可能有一份包含必要信息的日志。
手动阅读这些信息会花费太多时间,但Python可以帮助筛选这些信息。
这样分析师就能找到他们需要的东西。再举一个例子。
分析师可以使用Python来管理访问控制列表。
即控制谁可以访问系统及其资源的列表。
如果每次有员工离职,分析师都必须手动移除其访问权限,这可能会降低一致性。
然而,一个Python程序可以定期监控并自动执行此操作。
或者,Python也可以执行一些自动化任务,比如分析网络流量。
虽然这些任务可以通过外部应用程序完成,但使用Python同样可以实现。
除了自动化单个任务,Python还可以将独立的任务合并到一个工作流程中。
例如。想象一个操作手册指示分析师需要通过删除文件然后通知相关人员来解决某个情况。
Python可以将这些流程连接在一起。那么,安全专业人员究竟为何选择Python来完成这些任务呢?
Python作为一种编程语言具有几个优势。首先。
Python是用户友好的,因为它类似于人类语言。
它需要的代码更少,并且易于阅读。Python程序员还有一个好处,就是遵循标准指南,以确保代码设计和可读性的一致性。
学习Python的另一个重要原因是它有大量的在线支持。
Python还拥有一个庞大的内置代码库,我们可以导入并使用它来执行许多不同的任务。
这些只是Python在全球不同行业中持续保持高需求的部分原因。
在你的安全职业生涯中,你很可能会用到它。
总结 ✨
本节课中我们一起学习了编程在网络安全中的基础作用,特别是Python语言。我们了解到Python因其语法简洁、易于阅读、社区支持强大以及丰富的库,成为自动化安全任务(如日志分析、访问控制管理)的理想工具。它通过减少手动劳动和提高一致性,帮助安全分析师更高效地工作。


这些听起来都很棒。让我们稍作休息。接下来。
我们终于要开始运行一些Python代码了。我们下个视频再见。
045:4_04 创建基础Python脚本

概述
在本节课中,我们将学习如何编写并运行一个基础的Python脚本。我们将从理解脚本与程序的区别开始,然后实践编写包含注释和print函数的代码,最后运行它。
脚本与程序的区别
上一节我们介绍了Python的基础知识,本节中我们来看看如何实际编写代码。在Python中,我们编写的代码通常被称为脚本或程序。两者之间存在细微差别。
我们可以将计算机程序比作一场戏剧表演。几乎每场戏剧表演都有一份书面剧本。演员研究并背诵剧本,以便向观众念出台词。然而,这并非表演的全部。整个表演还包括导演对灯光、服装和舞台布景等做出的决策。整个表演涉及许多设计选择,例如场景设计、灯光和服装。
创建这场演出的过程类似于Python编程的过程。编程涉及许多设计决策。但在Python中编写脚本的过程,更像是撰写演员将要念出的具体台词。
编写你的第一个Python脚本
理解了基本概念后,我们现在开始动手编写代码。在Python中,良好的实践是从注释开始。
注释是程序员为说明代码意图而做的笔记。我们现在添加一个注释。我们以井号#开头,表明这是一行注释,然后添加关于我们意图的细节。
# 这行代码将在屏幕上打印“hello Python”
现在,让我们编写第一行Python代码。这段代码使用print函数。print函数将指定的对象输出到屏幕。在print之后,我们将要输出的内容放在括号内。在本例中,我们希望输出字符串“hello Python”。我们必须将字符串数据放在引号中。
print("hello Python")
这些引号只是你在Python中会遇到的一种语法示例。语法指的是决定计算语言中何为正确结构的规则。
运行你的代码
代码编写完成后,我们需要运行它,以便计算机能够输出这个字符串。
以下是运行代码的步骤:
- 打开你的Python环境(如IDLE、命令行或Jupyter Notebook)。
- 输入或粘贴我们编写的两行代码。
- 执行脚本。

你刚刚运行了你的第一行代码。由于我们的语法正确,字符串现在已显示在屏幕上。

总结
本节课中我们一起学习了Python脚本的基础。我们区分了脚本与程序的概念,实践了如何通过添加注释来说明代码意图,并使用print("hello Python")函数输出了第一个字符串。理解并正确使用语法是编写有效代码的关键。现在你已经体验了在Python中编写和运行代码,为学习其基本组件做好了准备。
046:5_06_网络安全工程师与Python


在本节课中,我们将了解Python编程语言在网络安全领域的核心价值。我们将探讨网络安全工程师为何需要掌握Python,以及如何开始学习并应用它来解决实际问题。
🎯 概述:Python在网络安全中的重要性
我的名字是阿卡什,我在谷歌担任安全工程师。作为一名网络安全工程师,在你的职业生涯中,你最终会在大部分工作中使用Python。当你进入网络安全领域时,学习Python非常重要。
你将处理数以百万计的数据点,手动处理这些数据会非常困难。这时就需要Python来编写脚本和小程序,实现自动化,在瞬间完成同样的任务。
💡 学习Python的益处与体验
学习Python非常有趣。当你看到大约10行代码就能在一秒钟内处理数兆字节的数据时,会非常有成就感。
Python拥有大量资源和非常乐于助人的开源社区。保持好奇心,从小问题入手,亲自动手实践。不要害怕查阅语法,要善于利用在线资源学习。
🛡️ 网络安全工程师的职责与挑战

作为谷歌Chrome的安全工程师,我的工作是保护我们的客户免受外国政府和世界各地持续威胁的攻击。

威胁是无限的,没有界限。这正是网络安全令人兴奋的地方。
🚀 持之以恒,掌握核心技能

坚持下去。Python是一项基本技能,初期需要一些时间来培养,但它将在你的整个职业生涯中为你服务。
📝 总结

本节课中,我们一起学习了Python对于网络安全工程师的关键作用。我们了解到,Python能高效处理海量数据,实现任务自动化,是应对无限网络威胁的必备工具。通过利用丰富的资源和社区,从小处着手实践,你将能逐步掌握这项强大的技能,并在充满挑战与机遇的网络安全领域持续成长。
047:Python中的数据类型 📊

在本节课中,我们将要学习Python中如何对数据进行分类。理解数据类型是编写有效代码的基础,它决定了数据如何被存储、处理和操作。
概述
在编程中,数据类型就像厨房中对食材的分类。正如胡萝卜和辣椒属于蔬菜,鸡肉和牛肉属于肉类,不同的数据类型决定了我们如何处理它们。Python使用数据类型来定义数据的类别,这对于执行正确的操作至关重要。本节我们将介绍五种核心数据类型:字符串、整数、浮点数、布尔值和列表。
数据类型简介
上一节我们提到了编程中分类的重要性。本节中,我们来看看Python具体有哪些主要的数据类型。
数据类型 是为特定类型的数据项定义的类别。Python支持多种数据类型,我们将重点学习以下五种:
- 字符串
- 浮点数
- 整数
- 布尔值
- 列表
字符串(String)
当我们之前打印文本“Hello, Python”时,这就是一个字符串的例子。
字符串 数据是由有序字符序列组成的数据。这些字符可以是字母、符号、空格,甚至是数字。但需要注意的是,字符串类型中的数字不能用于数学计算。
所有字符串中的字符必须放在引号内。幸运的是,如果你忘记加引号,Python会通过给出错误信息来提示你。
让我们用之前的代码来探索一下,当我们漏掉引号时会发生什么。
print(Hello, Python)
注意,字符串末尾缺少了一个引号。当我们运行这段代码时,会收到一个错误信息。
数值类型:浮点数与整数
Python同样支持数值数据类型。处理数值数据时,我们不需要在数据周围加引号。
数值数据包括浮点数和整数。
浮点数 是包含小数点的数字数据。这包括像 2.1 或 10.5 这样的分数,也包括带有小数点的整数,如 2.0 或 10.0。
整数 是不包含小数点的数字数据。像 0、-9 和 5000 这样的数字都是有效的整数。
到目前为止,我们使用 print 函数来输出字符串。但它也可以与浮点数和整数类型一起使用来进行计算。
让我们尝试一个例子。首先,按照良好实践,我们添加一个注释来解释代码的目的。
# 计算 1 + 1 的结果
print(1 + 1)
输出结果给出了答案:1加1等于2。
我们可以将 print 与浮点数和整数数据一起使用,来执行各种数学运算,如加法、减法、乘法和除法。
布尔值(Boolean)
Python中的第三种数据类型称为布尔型。
布尔 数据是只能为两个值之一的数据,即 True(真)或 False(假)。布尔值在我们程序的逻辑中非常有用。
例如,让我们比较数字并确定这些比较的布尔值。首先,我们使用 print 函数来评估10是否小于5。然后,我们也将评估9是否小于12。
print(10 < 5)
print(9 < 12)
那么你认为呢?10不小于5,但9小于12,对吧?让我们看看Python运行时如何处理。
第一行输出告诉我们,“10小于5”这个说法是False(假)。第二行告诉我们,“9小于12”这个说法是True(真)。当我们开始在代码中加入条件判断时,会更多地使用布尔值。
列表(List)
我们将要介绍的最后一个数据类型是列表。
列表 是一种数据结构,由按顺序排列的数据集合组成。我们将创建并打印一个列表,其中包含有权访问某个机密文件的三位用户的用户名。
首先,我们添加注释,说明意图是打印这个列表。在关键字 print 之后,我们添加列表。我们需要将列表放在方括号 [] 内。之后,我们将列表中的各个项目放在引号中,并用逗号分隔它们。

# 打印有权访问文件的用户列表
print(["elarson", "bmoreno", "tshah"])
好的,现在运行它。正如预期,我们得到了列表。当它打印时,仍然包含方括号。
这只是列表功能的开始。随着你Python技能的增长,你将学习如何访问和编辑列表中的单个项目。
总结
本节课中我们一起学习了Python中五种主要的数据类型:字符串、整数、浮点数、布尔值和列表。这些数据类型是我们后续课程中会经常用到的一些更常见的类型。理解它们将帮助你更好地组织和处理程序中的数据。
048:在Python中使用变量

概述
在本节课中,我们将要学习Python编程中的一个核心概念:变量。我们将了解什么是变量,如何创建和使用变量,以及变量在编写清晰、高效的代码中所扮演的重要角色。
变量:数据的容器
上一节我们介绍了不同的数据类型,就像烹饪中的食材分类。现在,我们来做一个新的比较。在厨房中,我们还会使用各种存储容器。这些容器可以存放许多不同的东西。一顿饭后,容器里可能装的是米饭;另一顿饭后,它可能装的是意大利面。类似地,在Python中,我们有变量。
一个变量是一个存储数据的容器。
以下是创建变量的步骤:
- 为变量想一个名字。
- 添加一个等号(
=)。 - 指定要存储在其中的对象。
创建变量通常被称为赋值。命名变量的最佳实践是让名字与其用途相关。
让我们用一个变量来存储一个设备ID。我们将变量命名为 device_id,使用等号(=),然后给它赋值 "h32rb17"。因为这个变量的数据类型是字符串,所以我们将该值放在引号中。
device_id = "h32rb17"
运行这行代码后,我们的变量就被保存到Python中了。
调用变量
创建变量的目的是为了在后续的代码中使用它们。使用变量也可以被称为调用它们。要调用一个变量,只需输入它的名字。这会告诉Python使用该变量所包含的对象。
让我们在刚刚写的代码基础上添加一行,来调用这个变量。我们将让它打印出这个变量。为此,我们使用 print() 函数,并让它打印存储在 device_id 变量中的值。
print(device_id)
在 print() 函数中使用变量时,我们不使用引号。这次当我们运行它时,有事情发生了:Python将 h32rb17 打印到了屏幕上。
变量与字符串的直接打印
我们再添加一行代码,来演示打印变量和直接打印字符串之间的区别。我们将让Python打印一个包含另一个设备ID的字符串:"m50pi31"。因为这是一个字符串数据而不是变量,所以我们把它放在引号里。
print("m50pi31")
现在,运行代码并查看结果。它执行了两个打印语句。第一个读取变量并打印其包含的值 h32rb17。第二个读取指定的字符串并打印 m50pi31。
既然我们可以直接使用这个字符串,为什么还需要变量呢?原因如下:
- 我们经常使用变量来简化代码,使其更清晰、更易读。
- 如果我们需要一个非常长的字符串或数字,将其存储在变量中可以让我们在整个代码中使用它,而无需每次都完整地打出来。
变量的数据类型
在上一个例子中,变量存储的是字符串数据。但变量可以存储各种数据类型。变量具有其当前存储对象的数据类型。
如果你不确定变量内部存储的数据类型,可以使用 type() 函数。type() 函数是一个返回其输入参数数据类型的函数。
让我们在Python中使用 type() 函数。我们首先创建变量,然后添加一行包含 type() 函数的代码。这行代码要求Python告诉我们 device_id 变量的数据类型,并将结果赋值给一个名为 data_type 的新变量。之后,我们可以将 data_type 变量打印到屏幕上。
device_id = "h32rb17"
data_type = type(device_id)
print(data_type)
运行后,Python告诉我们 device_id 包含的值是一个字符串(<class 'str'>)。
类型错误
在使用变量时,跟踪它们的数据类型非常重要。如果不这样做,可能会遇到类型错误。类型错误是由于使用了错误的数据类型而导致的错误。
例如,如果你尝试将一个数字和一个字符串相加,就会得到一个类型错误,因为Python无法将这两种数据类型组合在一起。它只能将两个字符串相加,或者将两个数字相加。
让我们演示一个类型错误。首先,我们将使用存储字符串值的 device_id 变量。然后,我们将定义另一个名为 number 的变量,并为其分配一个整数值。接着,我们写一个打印语句,输出这两个变量的和。
device_id = "h32rb17"
number = 15
print(device_id + number)
运行这段代码,我们最终会得到一个错误,因为我们不能将字符串与数字相加。
重新赋值变量
前面我们提到变量就像容器,它们里面装的东西是可以改变的。在我们定义了一个变量之后,我们总是可以改变它内部的对象。这被称为重新赋值。
重新赋值一个变量与最初给它赋值非常相似。让我们尝试重新赋值一个变量。我们首先将相同的字符串 "h32rb17" 赋值给变量 device_id,并包含一行代码来打印这个变量。现在,让我们尝试重新赋值这个变量。我们输入变量的名字、一个等号,然后添加新的对象。在这个例子中,我们将使用字符串 "n73abc07" 作为新的设备ID。我们还会让Python再次打印这个变量。
device_id = "h32rb17"
print(device_id)
device_id = "n73abc07"
print(device_id)

让我们看看运行这段代码会发生什么。Python打印了两行输出。第一个打印语句发生在重新赋值之前,所以它首先打印字符串 h32rb17。但第二个打印语句发生在它改变之后,这就是为什么屏幕上第二个输出是字符串 n73abc07。
通过这段代码,我们将一个具有字符串值的变量重新赋值为另一个字符串值。但是,也可以将一个变量重新赋值为另一种数据类型的值。例如,我们可以将一个具有字符串值的变量重新赋值为一个整数值。
总结
本节课中我们一起学习了Python中变量的核心概念。我们了解到变量是存储数据的容器,通过赋值来创建,通过变量名来调用。我们探讨了变量的数据类型以及因类型不匹配可能引发的类型错误。最后,我们学习了如何对变量进行重新赋值,这赋予了变量极大的灵活性。变量是Python中必不可少的部分,随着课程的深入,你会对它们越来越熟悉。
049:Python中的条件语句 🐍

在本节课中,我们将学习Python中条件语句的基础知识。条件语句是自动化任务的核心,它允许程序根据特定条件做出决策,从而执行不同的代码块。
概述
之前,我们讨论了如何在变量中存储不同的数据类型。现在,我们将开始进入自动化的概念,以便用代码创建令人兴奋的操作。
自动化是利用技术来减少执行常见和重复性任务所需的人工和手动劳动。它允许计算机为我们完成这些任务,从而让我们在生活中腾出更多时间去做其他活动。
条件语句对于自动化至关重要。
什么是条件语句?
条件语句是一种评估代码以确定其是否满足指定条件的语句。
关键字 if 在条件语句中非常重要。它用于开始一个条件语句。在这个关键字之后,我们指定必须满足的条件,以及如果满足条件将会发生什么。
我们每天都在使用 if 语句。例如,如果外面很冷,那么我们就穿夹克。或者如果下雨,那么我们就带伞。if 语句的结构包含我们想要评估的条件,以及如果条件满足时Python将执行的操作。
Python总是评估条件是真还是假。如果为真,它就执行特定的操作。
if 语句详解
让我们探索一个例子。我们将指示Python在任何时候失败登录尝试次数大于5时,打印一条“账户已锁定”的消息。
if failed_attempts > 5:
print("Account locked")
我们的关键字 if 告诉Python开始一个条件语句。之后,我们指明要检查的条件。在本例中,我们检查用户是否有超过5次的失败登录尝试。请注意我们如何使用一个名为 failed_attempts 的变量。在我们完整的代码中,我们会在 if 语句之前为 failed_attempts 赋值。
在这个条件之后,我们总是放置一个冒号 :。这表示冒号后面的内容是我们希望在条件满足时发生的事情。在本例中,当用户的失败登录尝试超过5次时,它会打印一条消息“账户已锁定”。
在Python中,这条消息应该始终缩进至少一个空格,以便仅在条件为真时执行。通常,我们将第一行称为头部,而将条件满足时发生的操作称为主体。
条件运算符
这个条件是基于一个变量大于一个特定数字。但我们可以使用各种运算符来定义我们的条件。
以下是常用的比较运算符:
- 大于:
>,检查一个值是否大于另一个值。 - 小于:
<,检查一个值是否小于另一个值。 - 大于或等于:
>=,检查一个值是否大于或等于另一个值。 - 小于或等于:
<=,检查一个值是否小于或等于另一个值。 - 等于:
==,在条件语句中比较两个对象是否相等。注意,这不是单个等号=(赋值),而是双等号==。 - 不等于:
!=,检查两个对象是否不相等。
双等号 == 是条件语句中常用的一个重要运算符。它评估两个对象是否匹配。当它们匹配时,它赋予布尔值 True;当它们不匹配时,赋予 False。
感叹号后跟等号 != 表示“不等于”的条件。这个“不等于”运算符评估两个对象是否不同。当它们不匹配时,它赋予布尔值 True;当它们匹配时,赋予 False。
使用 == 的示例
让我们更仔细地研究一个使用双等号的例子。我们将关注一个在特定操作系统运行时打印“需要更新”消息的示例。
if operating_system == "OS2":
print("Updates needed")
这里,我们创建了一个条件,用于检查设备的操作系统是否与标识该操作系统的特定字符串匹配。为此,我们需要在条件中使用双等号。当匹配时,我们的程序将打印一条消息“需要更新”。
变量 operating_system 在双等号的左边。字符串 "OS2" 在右边。如果条件评估为 True,它将执行下一行缩进的代码中的操作。在这里,如果操作系统是 OS2,它将打印“需要更新”。如果为 False,则不会打印该消息。
请注意这一行是如何缩进的。这告诉Python该任务依赖于 if 语句评估为 True。
现在,让我们编写包含此条件的代码并获取结果。
# 首先,为操作系统变量赋值
operating_system = "OS2"
# 然后,编写条件语句
if operating_system == "OS2":
print("Updates needed")
由于我们将 operating_system 变量设置为 "OS2",所以 print 语句将会执行。运行此代码,正如预期的那样,它打印了“Updates needed”,因为分配给 operating_system 变量的值等于 "OS2"。
引入 else 语句
有时,我们希望条件语句在第一个条件不成立时执行另一组指令。在我们的例子中,“不成立”意味着设备运行的操作系统不是 OS2。这时我们需要将 else 关键字纳入我们的条件语句中。
else 位于一个代码段之前,该代码段仅当条件语句中所有先前的条件都评估为 False 时才执行。else 语句总是跟在 if 语句之后,并以冒号 : 结尾。
让我们使用之前的条件并为其添加一个 else 语句。
operating_system = "OS3" # 这次赋一个不同的值
if operating_system == "OS2":
print("Updates needed")
else:
print("No updates needed")
我们包含了相同的 if 语句。但这次,我们将 operating_system 变量设置为包含一个不同的操作系统 "OS3"。因为这不符合 if 语句条件中的值,所以“需要更新”的消息不会打印。但我们可以添加一个 else 语句,告诉它做其他事情。
我们输入 else 关键字,后跟一个冒号 :。然后我们缩进下一行,并告诉它打印一条“无需更新”的消息。
当我们运行这段代码时,它会在 if 语句之后处理 else 语句。由于我们的 if 语句将评估为 False,它就会继续执行 else 指令。运行代码,正如预期,它只打印了消息“No updates needed”。

总结
在本节课中,我们一起学习了Python中条件语句的基础知识。我们首先了解了自动化以及条件语句在其中的作用。然后,我们深入探讨了 if 语句的结构和工作原理,包括如何使用各种比较运算符(如 >、<、==、!=)来定义条件。最后,我们学习了如何使用 else 语句来处理条件不满足时的情况。掌握 if 和 else 的使用,可以让你将逻辑融入代码,这是实现自动化任务的关键一步。
050:9_03_for循环


概述
在本节中,我们将学习迭代语句,特别是for循环。迭代语句能让计算机重复执行特定任务,这在处理繁琐或重复性工作时非常有用。我们将了解for循环的语法、结构及其核心应用。
从条件语句到循环
上一节我们介绍了条件语句,它让计算机能够做出决策。但有时,我们需要程序简单地计数或一遍又一遍地执行某个任务。对于人类而言,重复性任务容易导致注意力分散和精力消耗。在这种情况下,计算机就显得尤为有用。
本节中,我们将探讨计算机如何使用迭代语句来执行重复任务。迭代语句,也称为循环,是一段能重复执行一组指令的代码。
什么是循环?
设置一个循环,可以让我们重复使用一行代码,而无需多次键入它。在讨论具体语法之前,我们先运行一个循环来感受一下它的效果。
for i in [1, 2, 3, 4]:
print(i)
请注意,这段代码仅用了一个print语句,就打印出了列表中的所有数字。这就是循环的作用。
我们将探讨两种类型的循环:for循环和while循环。刚才我们运行的就是一个for循环,本节我们将重点介绍它。后续课程会再探讨while循环。
for循环详解
for循环会为指定的序列重复执行代码。一个典型的例子是使用for循环打印列表中的每一项。
for循环以关键字for开头,它标志着循环的开始。与条件语句类似,迭代语句也由两个主要部分组成:循环头和循环体。
让我们仔细分析刚才运行的for循环,并以此探索这些部分。
循环头
循环头是包含for关键字并以冒号结尾的那一行。它告诉Python开始一个循环。循环头由以下部分组成:
for关键字。- 循环变量。
- 循环将遍历的序列。
循环变量是用于控制循环迭代的变量,它紧跟在for之后。一个常见的命名是字母i,但你可以给它起任何你想要的名称。在for循环中,这个临时变量仅在循环内部使用,不会在循环外的其余代码中使用。
循环变量后面跟着in操作符,以及循环将要遍历的序列。在我们之前的例子中,这个序列是一个包含数字1到4的列表。循环会将列表中的每个数字依次执行指定的操作。
重要提示:必须在循环头的末尾加上冒号,以引入后续的循环体代码。
循环体
循环体指的是循环头之后缩进的行。这些行代表了循环迭代时要重复执行的操作。在我们之前的例子中,循环体就是打印列表中的每个数字:先打印1,然后打印2,依此类推。
结合range函数使用for循环
for循环的另一个重要用途是,将特定过程重复执行设定的次数。这可以通过结合range函数来实现。
range函数会生成一个数字序列。例如,range(0, 10)会设定一个从0开始,一直到9的序列。
当我们使用range时,我们从第一个参数指定的数字开始计数(本例中是0)。当到达第二个参数指定的数字时,它告诉我们停止的位置,但这个数字本身被排除在外。因此,在本例中,第二个参数是10,序列只包含到9。
关于range函数的一个重要细节是:如果我们不提供起始点,它会自动从0开始。例如,range(10)中,10代表停止点。由于停止点被排除,序列中包含的数字从0开始,到9结束。一个从0开始到9结束的序列将迭代10次。
让我们运行一个结合了range函数的for循环。
for i in range(10):
print("无法连接到目标。")
我们使用range(10)来要求Python重复一个动作10次,然后我们指明想要重复的动作:打印一条“无法连接到目标”的错误信息。
运行这段代码,使用for循环结合range函数,我们得以将同一条错误信息重复10次,而无需我们自己一遍又一遍地键入它。

总结
在本节中,我们学习了迭代语句的语法和结构,并以for循环为例进行了实践。我们了解了循环头和循环体的构成,以及如何利用range函数来控制循环的迭代次数。在下一节视频中,我们将介绍另一种迭代语句:while循环。

051:while循环详解

概述
在本节课中,我们将要学习Python中的另一种迭代语句——while循环。我们将了解它的基本结构、工作原理,并通过一个网络安全相关的实际例子来掌握其应用。
从for循环到while循环
上一节我们介绍了Python中的迭代语句,并重点讲解了for循环。迭代语句是指能够重复执行一组指令的代码。
本节中,我们来看看另一种迭代语句:while循环。当我们使用for循环时,代码是基于一个指定的序列来重复执行的。而while循环虽然也重复执行,但这种重复是基于一个条件的。只要条件为真,循环就会继续执行;当条件变为假时,while循环就会停止。
例如,这个while循环设置了一个条件:变量time必须小于或等于10。这意味着只要变量time不大于10,循环就会一直运行。
while循环的结构
与for循环类似,while循环也有一个头部。它由关键字while、条件和一个冒号组成。
while循环以关键字while开始。关键字while标志着while循环的开始,后面跟着一个计算结果为布尔值(True或False)的条件。
条件中包含循环变量。这个变量用于控制循环的迭代次数。然而,for循环和while循环在变量使用上有一个重要区别:在while循环中,变量不是在循环语句本身内部创建的。在编写while循环之前,你需要先给变量赋值,然后才能在循环中引用它。
当包含循环变量的条件计算结果为True时,循环就会迭代。如果条件不为True,循环就会停止。在这个例子中,只要变量time小于或等于10,条件就会评估为True。最后,循环头部以一个冒号结束。
就像for循环一样,while循环有一个缩进的循环体,其中包含了循环迭代时要执行的操作。
while循环的工作原理
这段代码的目的是打印一个代表时间的变量的值,并将其值增加2,直到它大于10。这意味着这个while循环的第一个操作是简单地打印当前time变量的值。
由于while循环不包含要遍历的序列,我们必须在while循环体中明确定义循环变量如何变化。例如,在这个while循环中,我们每次迭代都将循环变量time增加2。这是因为我们只想每两分钟打印一次时间。所以,这个while循环会打印出所有小于等于10的偶数。
网络安全应用实例:监控设备连接
现在我们已经了解了while循环的基础知识,让我们来探索一个实际例子。想象一下,我们对用户可以连接的设备数量有一个限制。我们可以使用while循环在用户达到最大连接设备数时打印一条消息。
以下是创建这个while循环的步骤:
- 初始化变量:在开始
while循环之前,我们需要为两个变量赋值。首先,我们将最大连接设备数max_devices设置为5。然后,我们设置循环变量i,并将其初始值设为1。与for循环不同,在while循环中,我们在循环外部设置这个变量。 - 创建循环头部:接下来,我们创建
while循环的头部。在这个例子中,条件是第一个变量i小于第二个变量max_devices。由于我们知道max_devices的值是5,我们可以理解这个循环将在i的当前值小于5时一直运行。 - 定义循环体:然后,我们指明希望
while循环做什么。因为这个循环在用户还能连接设备时运行,所以我们首先让它打印一条“用户仍可连接额外设备”的消息。在此之后,每次迭代,我们将i增加1。当循环重复时,它将使用i变量的新值。当i不再小于5时,Python将退出循环。 - 添加循环后操作:我们还需要在循环退出时打印一条消息。我们停止缩进,因为下一个操作发生在循环外部。然后我们打印“用户已达到最大连接设备数”。
让我们运行这段代码。由于循环的作用,第一条消息总共打印了四次。当i的值增加到5时,循环停止。此时,它退出循环并打印第二条消息。
# 示例代码
max_devices = 5
i = 1
while i < max_devices:
print("用户仍可连接额外设备。")
i += 1
print("用户已达到最大连接设备数。")

总结

本节课中,我们一起学习了Python中的while循环。我们了解了它的语法结构,即基于一个条件来重复执行代码块。我们探讨了它与for循环的关键区别:while循环的循环变量需要在循环外部初始化,并在循环体内手动更新。最后,我们通过一个限制用户连接设备数量的网络安全场景实例,实践了如何构建和应用while循环。当你将for循环和while循环的新知识与条件语句和变量等已有知识结合起来时,你在Python中就有了很多强大的工具可供选择。
052:课程回顾

在本节课中,我们将回顾之前学习的关键Python编程概念,这些知识对于网络安全分析师至关重要。我们将总结编程基础、数据类型、变量、条件语句和循环语句的核心要点。
课程内容回顾
上一节我们探讨了迭代语句,现在让我们系统地回顾一下到目前为止所学的全部内容。
你首先学习了编程的基础知识,以及为什么编程是网络安全分析师非常重要的工具。你还学习了一些关于编程语言工作原理的基本概念。
接下来,我们学习了识别Python中的数据类型。我们重点介绍了以下几种:
- 字符串:用于表示文本,例如
"警报"或"192.168.1.1"。 - 整数:用于表示没有小数部分的数字,例如
404或1024。 - 浮点数:用于表示带有小数点的数字,例如
3.14或99.5。 - 布尔值:用于表示逻辑真或假,即
True或False。 - 列表:用于存储有序的元素集合,例如
[‘GET’, ‘POST’, ‘PUT’]。
然后,我们重点学习了如何使用变量。变量就像一个带标签的盒子,用于存储数据,你可以通过变量名来访问或修改其中的数据。例如:
ip_address = "10.0.0.1"
status_code = 200
之后,你全面学习了条件语句,以及如何使用Python语句检查逻辑条件。if, elif, else 语句允许程序根据不同的条件执行不同的代码块。例如:
if failed_login_attempts > 5:
print("触发账户锁定警报")
else:
print("登录尝试正常")
最后,我们学习了迭代语句,并讨论了两种类型的循环:for 循环和 while 循环。for 循环通常用于遍历序列(如列表),而 while 循环会一直执行,直到指定的条件不再为真。例如:
# for循环示例
for log in suspicious_logs:
analyze(log)
# while循环示例
while connection_active:
monitor_traffic()
总结与展望

本节课中,我们一起学习了Python编程的核心基础,包括其重要性、基本结构、数据类型、变量、条件判断和循环控制。这些是构建自动化安全脚本和分析工具的基石。
随着你在本课程中的深入以及在网络安全分析师职业生涯中的发展,你将不断运用这些知识。
在接下来的章节中,我们将探索Python的其他重要组成部分,包括函数。函数可以帮助你将代码组织成可重复使用的模块,让程序更加清晰和高效。
053:12_01_welcome-to-week-2


在本节课中,我们将继续学习Python编程,重点介绍如何编写更高效、更易读的脚本。我们将学习函数、模块和库,以及提升代码可读性的最佳实践。
欢迎回到我们的Python学习之旅。在之前的视频中,我们学习了Python的基础知识。我们从最初开始,了解了安全分析师如何使用Python。我们学习了Python的几个基础构建块,并详细学习了数据类型、变量和基本语句。
现在,我们将在此基础上继续学习,了解更多关于如何编写高效Python脚本的知识。我们将探索如何让我们的工作更有效率。
接下来的视频将首先介绍函数,这在Python中非常重要。函数允许我们将一组指令组合在一起,以便在代码中反复使用。
之后,我们将学习Python的模块和库。它们包含了我们可以与Python一起使用的函数和数据类型的集合。它们帮助我们获得函数功能,而无需我们自己创建。
最后,我们将讨论编程中最重要的规则之一,即代码可读性。我们将学习如何确保每个人都能理解并使用你的代码。

很高兴你决定继续和我一起学习Python。让我们开始学习更多内容吧。

本节课中,我们一起学习了本周的学习目标,包括函数、模块与库以及代码可读性。这些知识将帮助我们构建更强大、更易于维护的Python脚本,以自动化网络安全任务。
054:函数简介

在本节课中,我们将要学习Python编程中的一个核心概念——函数。我们将了解函数是什么、为什么它们如此重要,以及它们如何帮助我们编写更高效、更易于维护的代码。
概述:为什么需要函数?
随着程序复杂度的增加,我们很可能会重复使用相同的代码行。多次编写相同的代码会非常耗时。幸运的是,我们可以使用函数来管理这种情况。函数是程序中可以重复使用的一段代码。
函数是什么?
我们之前已经学习过一个函数:print函数。我们用它来将指定的数据输出到屏幕,例如,我们打印了 print("hello Python")。除了print,Python中还有许多其他函数。
有时,我们需要自动化一些如果手动操作会非常重复的任务。为了帮助理解,我们可以将Python的关键组件与厨房元素进行类比。
类比理解:厨房里的函数
之前,我们将数据类型比作不同类别的食物。处理蔬菜和处理肉的方式不同,同样,处理不同数据类型的方式也不同。
接着,我们讨论了变量,它们就像餐后存放食物的容器,里面装的东西可以改变。
至于函数,我们可以把它们想象成洗碗机。如果不使用洗碗机,你将花费大量时间单独清洗每一个盘子。但洗碗机自动化了这个过程,让你可以一次性清洗所有餐具。类似地,函数提高了编程效率。它们在程序中执行重复性的活动,使程序能够有效地工作。
函数的核心优势
函数在我们的程序中被设计为可重复使用。它们由一系列小指令组成,可以在程序中的任何地方被调用任意多次。
函数的另一个好处是,如果我们需要修改它们,我们可以直接在函数内部进行更改,这个更改会应用到所有使用该函数的地方。这远比在程序中的许多不同位置进行相同的修改要好得多。
函数的类型
print函数是内置函数的一个例子。内置函数是Python中已经存在的函数,可以直接调用。它们默认就可供我们使用。
我们也可以创建自定义函数。自定义函数是程序员根据特定需求设计的函数。

总结:函数的价值

无论是内置函数还是自定义函数,都像是大程序中的迷你程序。它们让Python编程变得更加高效和有效。
在接下来的学习中,我们将继续深入探索函数的创建和使用方法。
055:创建基础函数

在本节课中,我们将学习如何创建和运行一个非常简单的用户自定义函数。我们将从定义函数开始,然后调用它来执行特定任务。
定义函数
上一节我们介绍了函数的概念,本节中我们来看看如何具体定义一个函数。定义函数就是告诉Python这个函数的存在。为此,我们需要使用 def 关键字。
以下是定义一个函数的基本步骤:
- 使用
def关键字。 - 为函数命名。
- 在函数名后添加括号
()。 - 在行末添加冒号
:。 - 在缩进的代码块中编写函数要执行的操作。
让我们创建一个在员工登录后向其问候的函数。首先,我们通过注释说明代码的意图。
# 定义一个问候员工的函数
def greet_employee():
print("欢迎登录!")
在这段代码中,greet_employee 是函数名。括号 () 目前是空的,因为我们这个简单的函数不需要接收任何外部信息。冒号 : 表示函数头的结束,而缩进的 print 语句是函数体,它定义了函数被调用时要执行的操作。
调用函数
仅仅定义函数并不会让它运行。要执行函数内的代码,我们必须调用它。调用函数就像使用Python内置的 print() 函数一样。
以下是调用函数的步骤:
- 在函数定义之后,另起一行。
- 直接写出函数名,并在后面加上括号
()。
让我们调用刚才定义的 greet_employee 函数。
# 调用问候函数
greet_employee()

当我们运行包含定义和调用的完整代码时,控制台就会输出我们预设的欢迎消息。
总结

本节课中我们一起学习了如何创建和运行一个基础的Python函数。我们首先使用 def 关键字定义了一个名为 greet_employee 的函数,该函数在被调用时会打印一条欢迎信息。随后,我们通过写出函数名并加上括号 () 的方式调用了这个函数,从而成功执行了函数体内的代码。这是一个简单但完整的函数使用流程。
056:在函数中使用参数


在本节中,我们将学习如何在Python函数中使用参数。参数允许函数接收外部信息,从而使函数的功能更加灵活和强大。我们将从理解参数的基本概念开始,然后学习如何定义带参数的函数,以及如何调用它们。
理解参数与函数
上一节我们介绍了如何定义和调用一个简单的函数。那个函数不需要任何外部信息。但其他函数可能需要。
这意味着我们需要讨论如何在函数中使用参数。在Python中,参数是包含在函数定义中、供函数内部使用的对象。
函数通过其名称后的圆括号来接收参数。我们上一节创建的函数没有接收任何参数。
现在,让我们回顾另一个使用参数的函数:range。如果你还记得,range函数会生成一个从起点到终点前一个值的数字序列。
因此,range函数包含了用于起点和终点的参数,每个参数都接受一个整数值。例如,它可以接受整数3和7。这意味着它生成的序列将从3运行到6。
定义带参数的函数
在我们的上一个例子中,我们编写了一个在有人登录时显示欢迎信息的函数。如果我们在信息中包含员工的名字,它会显得更加友好。
让我们定义一个带参数的函数,以便我们可以按名字问候员工。
当我们定义函数时,我们将包含函数所依赖的参数名称。我们将这个参数(name变量)放在括号内。语法的其余部分保持不变。
def greet_employee(name):
现在,让我们转到下一行并缩进,以便告诉Python我们希望这个函数做什么。我们希望打印一条使用传入函数的名字来欢迎员工的信息。
在函数中使用参数
将变量引入我们的打印语句需要考虑几点。和之前一样,我们从要打印的欢迎信息开始。但在这种情况下,我们不会在告诉他们已登录后就停止信息。我们希望继续并将员工的名字添加到信息中。
这就是为什么我们在“you logged in”后面放一个逗号,然后添加name变量。由于这是一个变量而不是特定的字符串,我们不用引号括起它。
def greet_employee(name):
print("Welcome, " + name + "! You are now logged in.")
现在我们的函数已经设置好,我们准备用一个特定的实参来调用它。在Python中,实参是在调用函数时带入函数的数据。例如,之前我们将3和7传递给range函数,这些就是实参。
在我们的例子中,假设我们想问候一位名叫Charlie Patel的员工。我们将用这个实参调用我们的greet_employee函数。
greet_employee("Charlie Patel")
当我们运行这段代码时,Charlie Patel会收到一条个性化的欢迎信息。
使用多个参数
在这个例子中,我们的函数只有一个参数。但我们可以有更多参数。让我们探索一个这样的例子。
也许我们不是只有一个name参数,而是有一个first_name参数和一个last_name参数。如果是这样,我们需要像这样调整代码。
首先,当我们定义函数时,我们包含两个参数并用逗号分隔它们。
def greet_employee_full(first_name, last_name):
然后,当我们调用它时,我们也包含两个实参。这次,我们问候一位名叫Kiara Karu的人。这些实参也用逗号分隔。
greet_employee_full("Kiara", "Karu")
让我们运行这些代码来欢迎Kiara Karu。正如我们刚刚探索的,使用多个参数只需要进行一些调整。


总结
在本节课中,我们一起学习了如何在函数中使用参数。我们了解了参数和实参的区别,学习了如何定义接收单个或多个参数的函数,以及如何通过传递实参来调用这些函数。这种理解在你继续编写Python脚本时将非常必要。😊
057:return语句


在本节课中,我们将要学习如何从函数中返回信息。我们将了解return语句的作用,并通过一个网络安全相关的实例——分析登录尝试失败率——来掌握其用法。
从函数中获取信息
上一节我们介绍了如何向函数传递参数。本节中我们来看看如何从函数中向外发送信息。
return语句允许我们实现这个功能。return语句是一条在函数内部执行的Python语句,它将信息发送回函数调用处。
对于安全分析师而言,从函数中返回信息的能力有多种用途。例如,分析师可能编写一个函数来检查某人是否有权访问特定文件,并向主程序返回一个布尔值True或False。
我们将探索另一个例子。让我们创建一个与分析登录尝试相关的函数。
创建计算失败率的函数
基于传入的信息,这个函数将计算登录失败的百分比,并返回这个百分比。程序可以多种方式使用这个信息,例如,用于决定是否锁定账户。
让我们开始学习如何从函数中返回信息。和之前一样,我们首先定义函数。
我们将它命名为calc_fails,并设置两个与登录尝试相关的参数:total_attempts(总尝试次数)和failed_attempts(失败次数)。
接下来,告诉Python我们希望这个函数做什么。我们希望这个函数将失败尝试的百分比存储在一个名为failed_percentage的变量中。
我们需要用失败次数除以总次数来得到这个百分比。到目前为止,这与我们之前学过的内容相似。
但现在,让我们学习如何返回failed_percentage。为此,我们需要使用关键字return。
return用于从函数中返回信息。在我们的例子中,我们将返回刚刚计算出的百分比。所以在关键字return之后,我们输入failed_percentage,这是包含此信息的变量。
现在,我们准备调用这个函数。我们将计算一个登录4次、失败2次的用户的失败百分比。
所以我们的参数是4和2。当我们运行它时,函数返回失败尝试的百分比,即0.5或50%。
处理函数的返回值
但在某些Python环境中,这个值可能不会直接打印到屏幕上。我们无法在函数外部使用特定的变量名failed_percentage。
因此,为了在程序的其他部分使用这个信息,我们需要从函数返回值并将其赋给一个新变量。
让我们来验证一下。这次,当函数被调用时,返回的值被存储在一个名为percentage的变量中。
然后我们可以在后续代码中使用这个变量。例如,我们可以编写一个条件判断,检查失败尝试的百分比是否大于或等于50%。
当条件满足时,我们可以让Python打印一条“账户已锁定”的消息。让我们运行这段代码。
这次,百分比没有直接返回到屏幕,取而代之的是我们得到了“账户已锁定”的消息。

接下来,我们将讨论更多关于函数的内容。但下一次,我们将介绍一些Python内置的、可以直接使用的函数。

总结
本节课中我们一起学习了return语句。我们了解到return语句用于从函数中向外发送信息,这对于编写模块化和可重用的代码至关重要。我们通过一个计算登录失败率的网络安全实例,实践了如何定义带return语句的函数,以及如何在调用函数时接收和使用其返回值。
058:探索内置函数

在本节课中,我们将要学习Python的内置函数。我们将回顾一些已学过的函数,并探索几个新的内置函数,同时了解如何将它们组合使用。
概述
上一节我们介绍了如何创建自定义函数。本节中,我们来看看Python提供的一些内置函数。内置函数是Python自带的、可以直接调用的功能。我们的任务就是通过它们的名字来调用它们。
回顾已学内置函数
我们已经在本课程中描述过一些内置函数,例如 print 和 type 函数。在学习新函数之前,让我们快速回顾一下这两个。
print函数:输出指定的对象到屏幕。- 代码示例:
print("Hello, World!")
- 代码示例:
type函数:返回其输入参数的数据类型。- 代码示例:
type(100)
- 代码示例:
之前,我们一直是独立地使用这些函数。例如,我们让Python打印某些内容,或者让Python返回某些内容的数据类型。
函数的组合使用
随着我们开始深入学习函数,我们经常需要将多个函数组合在一起使用。我们可以通过将一个函数作为参数传递给另一个函数来实现这一点。
例如,在这行代码中:
print(type("hello"))
Python首先返回 "hello" 的数据类型(一个字符串),然后这个返回值被传递给 print 函数。这意味着字符串的数据类型将被打印到屏幕上。
print 和 type 并不是唯一可以这样组合使用的函数。在所有情况下,通用语法是相同的:先处理内层函数,然后将其返回值传递给外层函数。
理解函数的输入与输出
使用函数时,你必须理解它们期望的输入和输出是什么。
- 有些函数只期望特定的数据类型,如果使用错误类型,会返回类型错误。
- 其他函数可能需要特定数量的参数,或者会返回不同的数据类型。
以下是关于函数输入输出的一些考虑:
print函数:可以接受任何数据类型作为输入。它也可以接受任意数量的参数,即使这些参数具有不同的数据类型。- 代码示例:
print("The value is", 100, "points.")
- 代码示例:
type函数:可以接受所有数据类型,但它只接受一个参数。- 代码示例:
type(73.2)
- 代码示例:
在使用内置函数之前,我们必须确切地知道它需要多少个参数、这些参数可以是哪些数据类型,以及它会产生什么样的输出。
探索新的内置函数
现在让我们学习几个新的内置函数,并思考它们的输入和输出。
max 函数
max 函数返回传递给它的最大数值输入。它没有定义可接受参数的数量限制。
让我们探索一下 max 函数。我们将以变量的形式传递三个参数给 max。
首先定义变量:
a = 3
b = 9
c = 6
然后,将这些变量传递给 max 函数并打印结果:
print(max(a, b, c))
运行这段代码,它会告诉我们这些值中最高的是 9。
sorted 函数
sorted 函数对列表中的元素进行排序。在处理列表时,这个函数在安全场景中非常有用。
- 对于数字列表,我们可能需要将它们从小到大(或从大到小)排序。
- 对于字符串数据列表,我们可能需要按字母顺序排序。
想象一下,你有一个包含组织中用户名的列表,并且你想按字母顺序对它们进行排序。让我们使用Python的 sorted 函数来实现。
首先,通过变量 usernames 指定我们的列表:
usernames = ["bob", "alice", "charlie", "david"]
现在,使用 sorted 函数通过将 usernames 变量传递给它来对这些名称进行排序。然后,将其输出传递给 print 语句,以便显示在屏幕上。
print(sorted(usernames))
运行它,所有名字现在都按顺序排列好了。

总结

本节课中我们一起学习了Python的内置函数。我们回顾了 print 和 type 函数,并学习了如何将函数组合使用。我们还探讨了理解函数输入和输出的重要性,并介绍了两个新的内置函数:用于查找最大值的 max 函数,以及用于对列表进行排序的 sorted 函数。这些只是可供你使用的众多内置函数中的一部分。随着你在Python中深入实践,你将熟悉更多有助于你编程的函数。
059:模块与库


概述
在本节课中,我们将要学习Python中的模块与库。我们将了解它们是什么、为什么有用,并探索Python标准库中的一些例子以及如何利用外部库来增强程序功能。
从内置函数到库
上一节我们介绍了如何在Python中构建函数。Python自带了许多内置函数,例如 print、type、max 等。
为了使用更多预先编写好的功能,你可以导入一个库。
什么是库与模块?
一个库是一个模块的集合,它为用户程序提供了可访问的代码。
所有的库通常由多个模块组成。
一个模块是一个Python文件,它包含额外的函数、变量、类以及任何种类的可运行代码。你可以把它们看作是包含了有用功能的已保存的Python文件。
模块可能由简单短小的代码行组成,也可能非常复杂和冗长。无论哪种方式,它们都能帮助程序员节省时间,并使代码更具可读性。
Python标准库
现在,让我们具体关注Python标准库。Python标准库是一个广泛的可使用Python代码集合,通常随Python一起打包安装。
以下是Python标准库中的几个模块示例:
re模块:这是一个对安全分析师非常有用的模块,当需要搜索日志文件中的模式时。csv模块:它允许你高效地处理CSV文件。sys和os模块:用于与命令行交互。time和datetime模块:用于处理时间戳。

这些只是Python标准库中的一小部分模块。
外部库
除了Python标准库中始终可用的内容,你还可以下载外部库。
以下是几个例子:
beautifulsoup4:用于解析HTML网站文件。numpy:用于数组和数学计算。
这些库将协助你作为安全分析师进行网络流量分析、日志文件解析和复杂数学运算。
总结
本节课中我们一起学习了Python的模块与库。总的来说,Python库和模块非常有用,因为它们提供了预先编程好的函数和变量,这为用户节省了时间。我们鼓励你探索我们在这里讨论的一些库和模块,以及它们在你使用Python工作时可能对你有帮助的方式。
060:代码可读性


欢迎回来。使用Python编程的优势之一在于它是一种非常易读的语言。
Python社区共享的一套指南也有助于编写整洁、清晰的代码。
这些指南被称为风格指南。风格指南是一本指导文档编写、格式和设计的手册。
在编程领域,风格指南旨在帮助程序员遵循相似的规范。
PEP 8风格指南是为Python程序员提供的风格指南资源。
PEP是Python增强提案的缩写。PEP 8为程序员提供了与语法相关的建议。
这些建议并非强制性的,但它们有助于在程序员之间建立一致性,确保他人能轻松理解我们的代码。
其核心原则是:代码被阅读的次数远多于被编写的次数。
对于任何希望以与其他程序员一致的方式学习和格式化其Python代码的人来说,这都是一个极好的资源。
注释
上一节我们提到了风格指南的重要性,本节中我们来看看其中的具体建议。首先是注释。
注释是程序员对其代码意图所做的说明。它们被插入到计算机程序中,以指示代码在做什么以及为什么这样做。
PEP 8给出了具体的建议,例如使注释清晰,并在代码更改时保持注释更新。
以下是一个没有注释的代码示例。编写它的人可能知道发生了什么。
但其他需要阅读它的人呢?他们可能不理解failed_attempts变量背后的上下文,以及为什么当它大于5时会打印“account locked”。
此外,原始作者未来可能需要重新审视这段代码,例如,为了开发更大的程序。没有注释,他们的效率也会降低。
failed_attempts = 6
if failed_attempts > 5:
print("account locked")
但在下面这个例子中,我们添加了注释。其他读者可以快速理解我们的程序及其变量在做什么。
# 检查登录失败尝试次数,超过5次则锁定账户
failed_attempts = 6
if failed_attempts > 5:
print("account locked")
注释应该简短且切中要点。
缩进
接下来,我们来谈谈代码可读性的另一个重要方面:缩进。
缩进是在一行代码开头添加的空格。这既能提高可读性,又能确保代码正确执行。
在某些情况下,您必须缩进行代码,以建立与其他行代码的连接。
这些缩进的代码行组成一个代码块,并与前面未缩进的一行代码建立联系。
条件语句的主体就是一个例子。

updates_needed = False
if updates_needed:
print("System updates are needed.")
我们需要确保print语句仅在条件满足时执行。此处的缩进向Python提供了这个指令。
如果print语句没有缩进,Python将在条件语句之外执行它,导致它总是被打印。
updates_needed = False
if updates_needed:
print("System updates are needed.") # 错误:缺少缩进
这将导致问题,因为即使不需要更新,您也会收到需要更新的消息。
要进行缩进,您必须在一行代码前添加至少一个空格。通常,程序员会添加两到四个空格以获得清晰的视觉效果。PEP 8指南建议使用四个空格。
风格指南的重要性
在我的第一份工程工作中,我编写了一个脚本来帮助验证和启动防火墙规则。起初,我的脚本运行良好,但一年后当我们试图扩展其功能时,它变得难以阅读。
在那一年里,我的编程知识和编码风格,以及我队友的编码实践都发生了变化。当时我们的组织没有使用编码风格指南,因此我们的代码风格迥异,难以阅读且不易扩展。
这带来了很多挑战,并需要额外的工作来修复。确保代码可读且能够随时间修改,这就是为什么安全专业人员遵循编码风格指南很重要,也是为什么风格指南对组织来说如此重要。
总结
在本节课中,我们一起学习了Python代码可读性的关键要素。我们了解了PEP 8风格指南的作用,探讨了如何编写清晰的注释来阐明代码意图,并掌握了使用正确缩进来组织代码结构的重要性。编写可读的代码是使用Python工作的关键能力。
随着我们进入课程的下一部分,我们将继续培养有效的编码实践,以进一步提升代码的可读性。
061:在网络安全团队中高效使用Python

概述
在本节课中,我们将学习如何在网络安全团队中高效地使用Python进行协作。我们将探讨团队合作的重要性、代码共享与规范化的价值,以及如何通过沟通和利用外部资源来提升个人与团队的效率。
大家好,我是Dorsa,是一名安全工程师。我工作中最热爱的一点是,每天都能接触到不同的基础设施和系统设计。
对于刚进入网络安全领域的个人,我有一条建议。
在Python开发中进行团队协作非常重要,其中一个关键方面是倾听团队成员提供的反馈。
当你在团队成员之间共享Python代码片段时,Python提供了许多不同的方式来访问不同的信息。
它能使代码更加统一,并使编码过程更有效率。
它使代码库更具可读性,并允许其他工程师在你之后继续完善你的代码。我见过很多行业实例,其中协作编写的Python代码起到了很大帮助。
其中一个例子是,在谷歌,我们编写了一个协作式的代码库,使得一个入职流程从6或7小时减少到几分钟。
协作是这个过程中的关键部分,否则,单靠一个人编写可能需要很多很多年。一个人无法理解每个系统的所有细节,如果没有多个工程师共同参与,这个过程会变得困难得多。
在团队中工作时,沟通非常重要,尤其是在用Python开发代码时。你需要表达在整个过程中是否需要帮助,因为你的团队成员的存在是为了确保你最终能够成功。归根结底,你的成功也意味着你团队的成功。
随着你作为Python代码编写者职业生涯的发展,你会发现互联网上有很多现成的函数和方法,通过快速搜索就能找到。这些方法会派上用场,你可以将它们复用到你的代码中。

一个让你学习新技能、扩展Python编码能力的绝佳资源是与你的同事交流。
参加技术聚会,与不在你公司工作的不同安全专业人士交谈,因为每个人对于如何提升你的编码技能,尤其是在网络安全领域的编码技能,都有独到的见解。
总结
本节课中,我们一起学习了在网络安全团队中高效协作使用Python的几个核心要点。我们认识到团队合作与倾听反馈是提升效率的基础,统一的代码规范能增强可读性与可维护性。通过沟通寻求帮助和复用现有代码资源,可以加速开发进程。最后,积极与同行交流是持续学习和技能提升的重要途径。将这些实践应用到工作中,将使你和你的团队在应对网络安全挑战时更加得心应手。
062:课程总结

在本节课中,我们将回顾并总结在Python课程中学到的核心概念,包括函数、模块与库,以及代码可读性与最佳实践。这些知识是使用Python高效自动化任务的基础。
函数的作用 🧩
上一节我们介绍了课程的整体目标,本节中我们来看看第一个核心概念:函数。
函数在Python中扮演着重要角色,它们能节省大量时间。我们学习了如何构建函数,以及如何开发自定义函数来满足特定需求。
- 核心作用:通过封装可重复使用的代码块来提升效率。
- 自定义函数:使用
def关键字定义,例如def my_function(parameter):。
模块与库 📚
理解了函数的基础后,我们可以进一步扩展工具集。本节将介绍模块与库。
模块和库为我们提供了远超Python内置功能的函数集合。通过导入它们,我们可以直接使用许多强大的工具。
以下是关于模块与库的关键点:
- 模块:一个包含Python定义和语句的文件(
.py文件)。 - 库:通常是相关模块的集合。
- 导入方法:使用
import语句,例如import os或from datetime import datetime。
代码可读性与最佳实践 ✨
掌握了扩展功能的方法后,编写易于理解和维护的代码同样重要。本节将关注代码可读性与最佳实践。
我们学习了编写整洁、易懂代码的最佳实践。这包括使用有意义的变量名、添加注释以及遵循一致的代码风格(如PEP 8)。

- 目标:编写不仅自己能懂,他人也能轻松阅读和维护的代码。
- 实践建议:使用描述性变量名、编写文档字符串(
""")、保持一致的缩进。
总结与展望 🚀
本节课中我们一起回顾了Python中的几个关键概念:函数的基础与自定义、通过模块与库扩展功能,以及编写清晰代码的最佳实践。
基于这些理解,你已经为学习Python在任务自动化方面的强大能力做好了准备。这些技能将帮助你作为一名安全分析师继续前进。
感谢你花时间学习本课程。我们下一个视频再见。😊
063:欢迎来到第三周 😊

在本节课中,我们将学习如何更有效地处理网络安全工作中的数据。作为安全分析师,您将处理大量数据。能够开发管理这些数据的解决方案至关重要。我们将要学习的Python知识将对此大有裨益。
上一节中,我们为本章节的学习打下了基础。我们学习了数据类型和变量,也涵盖了条件语句和循环语句。我们还学习了如何构建函数,甚至创建了自己的函数。
本节中,我们将在几个方面深化这些知识。首先,您将学习更多关于处理字符串和列表的方法。我们将扩展您处理这些数据类型的方式,包括从字符串中提取字符或从列表中提取项目。
我们的下一个重点是编写算法。您将学习一套可以在Python中应用的规则,以解决与安全相关的问题。
最后,在探索使用正则表达式时,我们将进一步扩展搜索字符串的方法。
我们将有很多乐趣,并开始编写一些非常有趣的Python代码。😊 让我们立刻开始吧。

本节课中,我们一起学习了第三周的学习目标和内容概览。我们了解到,本周将重点深化字符串和列表的操作,学习编写算法来解决安全问题,并探索强大的正则表达式工具。这些技能将帮助我们更高效地处理和分析安全数据。
064:字符串操作

概述
在本节课中,我们将学习如何在Python中处理字符串数据。字符串操作在网络安全领域至关重要,例如,分析登录信息中的用户名模式。我们将回顾字符串数据类型,并学习其基本操作,包括创建字符串、获取长度、拼接以及使用字符串方法。
字符串基础回顾
字符串是由字符组成的有序序列。在Python中,字符串写在引号内,可以使用双引号或单引号。本课程主要使用双引号。
示例字符串:
"hello""1,2,3""number one"
变量可以存储字符串。例如,变量 my_string 存储了字符串 "security"。
数据类型转换:str() 函数
有时需要将其他数据类型(如整数或浮点数)转换为字符串。为此,我们引入内置函数 str()。
str() 函数:将输入对象转换为字符串。
将对象转换为字符串后,可以执行仅适用于字符串的操作,例如移除或重新排序其中的元素,这些操作对整数数据类型来说很困难。
实践:将整数转换为字符串
我们将对整数 123 应用 str() 函数。
new_string = str(123)
print(type(new_string))
运行后,变量 new_string 包含一个由字符 '1'、'2'、'3' 组成的字符串。print(type(new_string)) 的输出确认了其类型为字符串。
基本字符串操作
上一节我们介绍了如何创建和存储字符串。本节中,我们来看看几种基本的字符串操作。
1. 获取字符串长度:len() 函数
len() 函数返回对象中元素的数量。对字符串使用此函数可以告诉我们字符串包含多少个字符。
在网络安全中,此功能很有用。例如,我们知道IPv4地址最多有15个字符。安全专业人员可以使用 len() 函数检查IPv4地址是否有效:如果其长度超过15个字符,则可以判定为无效的IPv4地址。
实践:计算字符串长度
我们将计算字符串 "hello" 的长度,并将 len() 函数嵌套在 print() 函数中,以便先计算长度再打印结果。
print(len("hello"))
运行后,输出为 5,对应单词 "hello" 中的每个字母。
2. 字符串拼接
字符串拼接是将两个字符串连接在一起的过程。在Python中,可以使用加号 + 进行拼接。
实践:拼接字符串
我们将字符串 "hello" 和 "world" 拼接在一起。
print("hello" + "world")
运行后,得到 helloworld,两个字符串之间没有空格。需要注意的是,并非所有运算符都适用于字符串,例如,不能使用减号 - 来对两个字符串进行“相减”操作。
3. 字符串方法
方法是属于特定数据类型的函数。因此,在另一种数据类型(如整数)上使用字符串方法会导致错误。与其他函数不同,方法出现在字符串之后。
以下是两种常见的字符串方法:
.upper()方法:返回字符串的全大写副本。.lower()方法:返回字符串的全小写副本。
实践:使用字符串方法
让我们对字符串 "Hello" 应用 .upper() 方法。注意方法的独特语法:在字符串 "Hello" 后加一个点 .,然后指定要使用的方法 upper。
print("Hello".upper())
运行后,屏幕打印出全大写的 HELLO。
类似地,我们对字符串 "Hello" 应用 .lower() 方法。
print("Hello".lower())
运行后,屏幕打印出全小写的 hello。

总结
本节课中,我们一起学习了Python中字符串的基本操作。我们回顾了字符串的定义和创建方式,学习了如何使用 str() 函数进行类型转换。接着,我们探索了三种核心操作:使用 len() 函数获取字符串长度、使用 + 运算符进行字符串拼接,以及使用 .upper() 和 .lower() 方法改变字符串大小写。这些是处理文本数据的基础,在后续分析登录信息、检查数据格式等网络安全任务中会经常用到。接下来,我们将深入学习更多关于字符串的知识,例如字符串索引和分割。
065:字符串索引与切片


在本节课中,我们将要学习Python中字符串的索引和切片操作。这些是处理和分析文本数据的基础,对于网络安全任务(如搜索日志文件中的特定信息)至关重要。
概述
在网络安全领域,我们经常需要搜索字符串。例如,我们可能需要在安全日志中定位一个用户名,或者在网络日志中搜索与恶意软件关联的特定IP地址。能够使用Python进行此类操作的第一步,就是了解字符串中字符的索引。
字符串索引
索引是一个分配给序列中每个元素的数字,用于指示其位置。对于字符串,索引就是每个字符在字符串中的位置。
以字符串 "hello" 为例。在Python中,字符串中的每个字符都被分配了一个索引,并且索引从0开始计数。因此,字符 'H' 的索引是 0,'e' 的索引是 1,依此类推。
让我们在Python中实践如何使用索引。将索引放在字符串后面的方括号中,可以返回该索引位置的字符。
"hello"[1]
运行这行代码,将返回字符 'e'。请记住,索引从0开始,所以索引 1 对应的是字符串中的第二个字符。
字符串切片
如果我们想提取字符串中不止一个字符的部分,该怎么办?这时可以使用切片操作。切片允许我们通过指定起始和结束索引来提取字符串的一部分。
切片语法是:string[start:end]。其中:
start索引是切片的起始位置(包含在输出中)。end索引是切片的结束位置(不包含在输出中)。Python会在第二个索引之前的元素处停止切片。
例如,如果我们想从 "hello" 中提取字母 'e', 'l', 'l'(即索引1, 2, 3),我们需要从索引 1 开始,在索引 4 之前结束。
"hello"[1:4]
运行这段代码,输出结果为 'ell',这正是我们想要的切片。
使用 index 方法搜索字符串
现在我们已经知道如何描述字符串中字符的位置,接下来学习如何在字符串中进行搜索。为此,我们需要使用字符串的 index 方法。
index 方法用于查找输入内容在字符串中第一次出现的位置,并返回其索引。
让我们在Python中练习使用 index 方法。假设我们想在字符串 "hello" 中找到字符 'e' 的位置。
"hello".index("e")
详细看一下这行代码:在写出字符串后,我们使用 .index() 方法,并将我们想要查找的字符 "e" 作为该方法的参数。请注意,Python字符串是区分大小写的,因此在使用 index 方法时需要确保大小写匹配。
运行这段代码,返回数字 1。这是因为 'e' 的索引值是 1。
现在,让我们探索一个字符在字符串中重复多次的例子。尝试搜索字符 'l'。
"hello".index("l")
运行这段代码,结果是索引 2。这告诉我们,index 方法只识别字符 'l' 的第一次出现,而不是第二次。这是使用 index 方法时需要注意的一个重要细节。
作为安全分析师,学习如何使用索引可以让你在字符串中找到特定部分。例如,如果你需要找到电子邮件中 @ 符号的位置,你可以用一行代码使用 index 方法找到它。
字符串的不可变性
现在,让我们将注意力转向字符串的一个重要特性:不可变性。
在Python中,字符串是不可变的。这意味着字符串在创建并被赋值后,其内容无法被更改。
让我们通过一个例子来理解这一点。首先将字符串 "hello" 赋值给变量 my_string。
my_string = "hello"
现在,如果我们想将字符 'e' 改为 'a',让 my_string 的值变成 "hallo",我们可能会尝试使用索引表示法来直接修改。
my_string[1] = "a" # 这行代码会导致错误
但是,这样操作会导致一个错误。因为 my_string 是不可变的,所以我们不能以这种方式进行更改。


总结
本节课中我们一起学习了字符串的索引和切片操作。你学会了如何通过索引定位单个字符,以及如何使用切片提取字符串的一部分。我们还探索了如何使用 index 方法在字符串中搜索内容。最后,你了解了字符串的一个重要特性——不可变性,这意味着字符串在定义后,其中的字符不能被重新赋值。
接下来,我们将学习列表操作,并会发现列表是可以通过索引表示法来改变的。


066:列表操作详解

在本节课中,我们将要学习Python中一个非常重要的数据结构——列表。我们将了解如何创建列表、访问其中的元素、修改列表内容,以及如何添加和删除元素。这些技能对于处理网络安全中的各类数据集合至关重要。
列表简介与创建
上一节我们介绍了字符串,本节中我们来看看另一种数据类型:列表。
列表非常有用,因为它允许你在单个变量中存储多个数据片段。在网络安全领域,你将处理各种列表。例如,你可能有一个可以访问网络的IP地址列表,而另一个列表可能包含被禁止在系统上运行的应用程序信息。
让我们回顾一下如何在Python中创建列表。列表中的项目用逗号分隔,并用方括号包围。
my_list = ['A', 'B', 'C', 'D', 'E']
我们也可以将列表赋值给一个变量,以便后续使用。这里,我们将变量命名为my_list。
访问列表元素
访问列表中的特定元素时,使用的语法与访问字符串中的特定元素类似。我们将索引值放在存储列表的变量后面的方括号中。
second_element = my_list[1]
这将访问列表中的第二个项目。这是因为在Python中,我们从0开始计数,而不是从1开始。因此,第一个元素的索引是0,第二个元素的索引是1。
让我们尝试从列表中提取一些元素。我们将通过将数字1放在变量后的方括号中来提取第二个元素,并将其放入print函数以输出结果。
print(my_list[1])
运行后,Python会输出字母B。
列表的拼接
与字符串类似,我们也可以使用加号来拼接列表。列表拼接是将两个列表合并为一个,方法是将第二个列表的元素直接放在第一个列表的元素之后。
让我们在Python中实践一下。首先,我们定义与之前示例相同的列表,并将其存储在变量my_list中。现在,我们再定义一个包含数字1到4的列表。最后,我们用加号拼接这两个列表并打印结果。
my_list = ['A', 'B', 'C', 'D', 'E']
another_list = [1, 2, 3, 4]
concatenated_list = my_list + another_list
print(concatenated_list)
运行后,我们会得到一个拼接后的最终列表。
列表与字符串的区别
在讨论了相似之处后,现在让我们探讨列表和字符串之间的区别。
我们之前提到字符串是不可变的,这意味着它们在定义后不能被更改。而列表则没有这个限制,我们可以自由地更改、添加和删除列表中的值。例如,如果我们有一个恶意IP地址列表,那么每当识别出一个新的恶意IP地址时,我们就可以轻松地将其添加到列表中。
让我们首先尝试在Python中更改列表中的特定元素。我们从前一个示例中使用的列表开始。要更改列表中的元素,我们需要结合使用方括号表示法和变量赋值。
my_list = ['A', 'B', 'C', 'D', 'E']
my_list[1] = 7
print(my_list)
我们将要更改的对象放在变量赋值的左侧。这里,我们将更改my_list中的第二个元素。然后,我们放置一个等号,表示我们要重新分配这个列表元素。最后,我们将要替换的对象放在右侧。运行代码后,字母B现在被更改为数字7。
插入和删除列表元素
现在,让我们看看在列表中插入和删除元素的方法。本视频中我们将使用的第一个方法是insert方法。
insert方法在列表的特定位置添加一个元素。该方法接受两个参数:第一个是我们要添加元素的位置,第二个是我们要添加的元素。
让我们使用insert方法。我们将从my_list变量中定义的列表开始。然后,我们输入my_list.insert并传入两个参数。第一个参数是我们想要插入新信息的位置,这里我们想插入到索引1处。第二个参数是我们想要添加到列表中的信息,这里是整数7。
my_list = ['A', 'B', 'C', 'D', 'E']
my_list.insert(1, 7)
print(my_list)
我们的列表仍然以A(索引为0的元素)开始。现在,我们在下一个位置(索引为1的位置)有了整数7。请注意,原本在索引1处的字母B并没有像使用方括号表示法时那样被替换。使用insert方法时,索引1之后的每个元素都简单地向下移动了一个位置。B的索引现在是2。
有时我们可能想从列表中删除一个不再需要的元素。为此,我们可以使用remove方法。remove方法会移除列表中第一次出现的特定元素。与insert不同,remove的参数不是索引值,而是直接键入你想要移除的元素。remove方法会移除列表中该元素的第一个实例。
让我们使用remove方法从列表中删除字母D。我们将输入变量名my_list,然后调用remove方法。我们想从列表中移除D,因此我们将其放在引号中作为参数。
my_list = ['A', 'B', 'C', 'D', 'E']
my_list.remove('D')
print(my_list)
运行后,D现在已从列表中移除。

总结
本节课中我们一起学习了Python列表的基本操作。我们了解了如何创建列表、通过索引访问元素、使用加号拼接列表,以及列表与字符串在可变性上的关键区别。我们还实践了使用方括号赋值来修改元素,以及使用insert和remove方法来动态地添加和删除列表中的元素。就像处理字符串一样,能够搜索和操作列表是安全分析师的一项必要技能。我们期待在课程后续内容中继续扩展对这些概念的理解。😊
067:编写简单算法 🧮

在本节课中,我们将要学习算法的基本概念,并了解如何将问题分解为步骤,最终使用Python编写一个简单的算法来解决网络安全中的实际问题。
什么是算法? 🤔
在我们的日常生活中,我们经常遵循规则来解决问题。一个简单的例子是,假设你想喝一杯咖啡。如果你多次制作过咖啡,那么你可能会遵循一个流程:首先,你拿起你最喜欢的杯子;然后,你将水倒入咖啡机并加入咖啡粉;接着,你按下启动按钮并等待几分钟;最后,你享用新鲜煮好的咖啡。
即使你有不同的煮咖啡方法或者根本不喝咖啡,你也可能遵循一套规则来完成类似的日常任务。当你完成这些常规任务时,你就是在遵循一个算法。
算法是一套用于解决问题的规则。更详细地说,算法是一系列步骤,它从问题中获取输入,利用这个输入执行任务,并返回一个解决方案作为输出。
网络安全中的算法应用 🛡️
上一节我们介绍了算法的基本概念,本节中我们来看看算法如何在Python中用于解决网络安全问题。
想象一下,你作为一名安全分析师,有一个IP地址列表。你想提取每个IP地址的前三位数字,这将告诉你这些IP地址所属网络的信息。为了实现这个目标,我们将编写一个涉及多个已学Python概念的算法:循环、列表和字符串。
以下是存储为字符串的IP地址列表(出于隐私原因,示例中未显示完整地址):
IP = ["198.5.6.7", "192.168.1.1", "10.0.0.1"]
我们的目标是从每个地址中提取前三个数字,并将它们存储在一个新列表中。
分解问题:从单个IP地址开始 🧩
在编写任何Python代码之前,让我们先分解一下用算法解决这个问题的思路。如果你只有一个IP地址,而不是整个列表,问题会变得简单得多。
解决此问题的第一步是使用字符串切片从一个IP地址中提取前三位数字。
现在,让我们考虑如何将其应用于整个列表。作为第二步,我们将使用一个循环将该解决方案应用于列表中的每个IP地址。
实现步骤一:字符串切片 ✂️
之前你已经学习了字符串切片。让我们编写一些Python代码来解决一个IP地址的问题。
我们从以“198.5.6.7”开头的IP地址开始,并编写几行代码来提取前三个字符。我们将使用方括号表示法来切片字符串。
address = "198.5.6.7"
print(address[0:3])
在打印语句中,address变量包含我们要切片的IP地址。请记住,Python从0开始计数,因此要获取前三个字符,我们从索引0开始切片,一直到索引3。Python会排除最终索引,换句话说,它将返回索引0、1和2处的字符。
运行此代码,我们得到地址的前三位数字:198。
实现步骤二:循环与列表操作 🔄
现在我们已经能够解决一个IP地址的问题,我们可以将此代码放入循环中,并将其应用于原始列表中的所有IP地址。
在开始之前,让我们介绍一个将在此代码中使用的方法:append方法。append方法将输入添加到列表的末尾。例如,假设my_list包含[1, 2, 3],使用以下代码,我们可以使用append方法将4添加到此列表中:
my_list = [1, 2, 3]
my_list.append(4)
print(my_list) # 输出: [1, 2, 3, 4]
现在我们已经准备好从列表中的每个元素中提取前三个字符。
首先,我们给定IP列表:
IP = ["198.5.6.7", "192.168.1.1", "10.0.0.1"]
然后,我们创建一个空列表来存储从列表中提取的每个IP地址的前三个字符:
networks = []
整合算法:循环遍历列表 📝
以下是整合后的算法实现。在循环开始前,我们先简要说明一下结构。
我们将使用一个for循环来遍历IP列表中的每个地址。在循环内部,我们对每个地址进行切片,并使用append方法将结果添加到networks列表中。
IP = ["198.5.6.7", "192.168.1.1", "10.0.0.1"]
networks = []
for address in IP:
# 提取前三个字符并添加到新列表
networks.append(address[0:3])
print(networks)
让我们分解一下for循环:
for告诉Python我们即将开始一个for循环。- 我们选择
address作为循环内的变量。 - 我们指定名为
IP的列表作为可迭代对象。 - 当循环运行时,
IP列表中的每个元素将临时存储在address变量中。 - 在
for循环内部,我们有一行代码将address的切片添加到networks列表中。这里使用了我们之前编写的代码来获取IP地址的前三个字符,并使用了append方法将其添加到networks列表的末尾。
最后,我们打印networks列表并运行代码。现在,networks变量包含了原始IP列表中每个IP地址前三位数字的列表。

总结 📚
本节课中我们一起学习了算法的概念,并通过一个网络安全中的实际例子——提取IP地址的网络前缀——实践了如何设计和实现算法。我们首先将问题分解为更小的步骤:先解决单个IP地址的切片问题,然后通过循环将其扩展到整个列表。我们还使用了append方法来构建新的列表。

设计算法可能具有挑战性,因此在开始编写代码之前,将其分解为更小的问题是一个好主意。在接下来的视频中,我们将继续练习这个思路。
068:正则表达式在Python中的应用

概述
在本节课程中,我们将学习如何使用正则表达式在Python中搜索字符串模式。正则表达式是一种强大的工具,能帮助我们从大量文本数据(如日志文件)中高效地提取特定模式的信息,例如IP地址或电子邮件地址。
从字符串操作到模式搜索
上一节我们学习了如何使用位置索引和切片来处理字符串,例如从一个IP地址列表中提取前三位数字。本节我们将关注一种更高级的字符串搜索方法:正则表达式。
正则表达式(常缩写为regex)是一个用于形成搜索模式的字符序列。这个模式可以用于在日志文件等文本中进行搜索。我们可以用它来查找任何类型的模式,例如所有以特定前缀开头的字符串,或所有特定长度的字符串。
在网络安全领域,正则表达式有多种应用方式。例如,假设我们需要找到所有网络ID为184的IP地址,正则表达式能让我们高效地搜索这种模式。
正则表达式的核心概念
为了理解正则表达式如何工作,让我们先学习两个基础符号。
加号 +
加号是一个正则表达式符号,代表其前面的字符出现一次或多次。
公式:a+
这个模式会匹配任何连续出现一个或多个“a”的字符串。例如,单个“a”、连续的三个“a”(aaa)或连续的五个“a”(aaaaa)都能匹配。
为了更直观地理解,请看以下包含设备ID的字符串示例:
a
aa
a
aaa
如果我们让Python查找匹配 a+ 模式的字符串,它将返回这个列表:[‘a‘, ‘aa‘, ‘a‘, ‘aaa‘]。
反斜杠加\w
\w 符号匹配任何字母数字字符(即字母a-z, A-Z, 数字0-9以及下划线_),但它不匹配符号。
代码:\w
例如,字符“1”、“K”和“i”都能被 \w 匹配。
组合模式:\w+
正则表达式的强大之处在于可以组合符号以创建更复杂的模式。在应用它们提取电子邮件之前,我们先看看将 \w 与 + 组合的效果。
\w 匹配任何字母数字字符,而 + 匹配其前面字符的任意多次出现。因此,\w+ 这个组合能匹配任意长度的字母数字字符串。
公式:\w+
\w 提供了匹配字符类型的灵活性,+ 则提供了匹配字符串长度的灵活性。字符串“192”、“ABC123”和“security”都是能被 \w+ 匹配的例子。
构建电子邮件地址的正则表达式
现在,让我们应用这些知识来从日志中提取电子邮件地址。电子邮件地址通常由被特定符号(如@和.)分隔的文本组成。
一个典型的电子邮件地址格式是:username@domain.com。
以下是构建匹配此模式的正则表达式的步骤:
- 用户名部分:由字母数字字符组成,长度可变。我们可以使用
\w+来匹配。 - “@”符号:这是电子邮件地址的固定部分。我们直接在表达式中写入
@。 - 域名部分:同样由字母数字字符组成,长度可变。我们再次使用
\w+。 - “.”符号:这也是固定部分。但在正则表达式中,点号
.本身是一个特殊字符(代表匹配任何单个字符)。为了匹配字面意义上的点号,我们需要在其前面加上反斜杠进行转义,即\.。 - 顶级域名:如“.com”、“.net”,也是字母数字字符串。我们继续使用
\w+。
将所有这些部分组合起来,就得到了用于查找电子邮件地址的完整正则表达式模式。
公式:\w+@\w+\.\w+
这个模式将匹配所有符合标准结构的电子邮件地址,并排除字符串中的其他内容,因为我们在模式中精确指定了 @ 和 . 出现的位置。
在Python中应用正则表达式
让我们将理论付诸实践,在Python中使用正则表达式从字符串中提取电子邮件地址。
要在Python中使用正则表达式,首先需要导入 re 模块。
代码:
import re
假设我们有一个多行字符串变量 email_log 存储了日志内容。我们将使用 re 模块的 findall() 函数。
re.findall() 函数接收两个主要参数:要匹配的正则表达式模式,以及要在其中搜索的字符串。它返回一个包含所有匹配项的列表。
代码:
# 假设 email_log 是一个包含日志文本的字符串变量
email_log = “““日志行1包含 user1@example.com
日志行2包含 another.email@domain.net
一些无关文本没有邮箱。”””
# 使用正则表达式查找所有电子邮件地址
email_addresses = re.findall(r‘\w+@\w+\.\w+‘, email_log)
# 打印结果
print(email_addresses)
运行这段代码,email_addresses 变量将包含一个列表:[‘user1@example.com‘, ‘another.email@domain.net‘]。
想象一下将这个技巧应用于包含数千条记录的日志文件,其效用将非常显著。


总结
本节课我们一起学习了正则表达式的基础知识。我们了解了如何使用 + 符号匹配重复字符,如何使用 \w 匹配字母数字字符,以及如何组合它们形成 \w+ 来匹配任意长度的字母数字字符串。最后,我们构建了一个完整的正则表达式模式 \w+@\w+\.\w+,并在Python中使用 re.findall() 函数成功从文本中提取出了所有电子邮件地址。这只是正则表达式强大功能的入门介绍,还有更多符号和技巧等待你去探索,以应对更复杂的模式匹配需求。
069:课程回顾与总结

在本节课中,我们将快速回顾并总结第七课所涵盖的所有核心概念。我们一起学习了如何操作字符串和列表、编写基础算法以及使用正则表达式,这些都是网络安全分析师处理数据和自动化任务的关键技能。
字符串与列表操作
上一节我们介绍了课程的整体目标,本节中我们来看看我们首先学习的内容:字符串和列表。
我们学习了专门用于处理这两种数据类型的方法。例如,使用.upper()方法将字符串转换为大写,或使用.append()方法向列表添加元素。
我们还学习了如何使用索引来定位和提取所需的信息。字符串和列表中的每个元素都有一个对应的位置编号,即索引,通常从0开始计数。
以下是处理字符串和列表时常用的几个操作示例:
- 字符串方法:
string.upper(),string.split() - 列表方法:
list.append(),list.index() - 索引与切片:
my_string[0],my_list[1:4]
算法编写
掌握了数据操作的基础后,我们进一步学习了如何编写简单的算法。
我们编写了一个从IP地址列表中提取网络ID的算法。这个过程涉及遍历列表、对每个字符串进行切片操作,并将结果组织起来。
以下是从IP地址"192.168.1.10"中提取前三个部分作为网络ID的核心代码逻辑:
ip_address = "192.168.1.10"
network_id = ".".join(ip_address.split(".")[:3]) # 结果为 "192.168.1"
正则表达式

最后,我们探讨了功能强大的工具——正则表达式。
正则表达式允许你基于特定模式进行搜索,这极大地扩展了在日志文件或其他文本中定位所需信息的能力。例如,模式\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}可以用来匹配一个IP地址。
这些概念较为复杂,你可以随时重温相关视频以加深理解。
总结与展望
本节课中我们一起学习了Python中处理字符串和列表的方法、编写基础算法的步骤,以及使用正则表达式进行模式匹配的技巧。

掌握这些概念,意味着你在处理安全数据、编写安全专业人员所需的算法方面迈出了一大步。在接下来的课程中,你将获得更多关于Python的实践机会,并深入了解它能为安全分析师提供的各种强大功能。
070:第四周导览


在本节课中,我们将学习如何将Python应用于实际的网络安全分析工作。我们将重点探讨如何处理安全日志文件,并学习如何调试代码以解决常见错误。
我们已经一起学习了Python的许多知识,但仍有更多内容需要探索。在本节中,我们将探讨像您这样的安全分析师如何将Python付诸实践。
作为一名安全分析师,您很可能会处理记录各种系统活动信息的安全日志。这些日志文件通常非常庞大,难以快速解读。但Python可以轻松地自动化这些任务,使工作变得更加高效。
因此,首先我们将重点学习如何在Python中打开和读取文件,这包括日志文件。之后,我们将探索如何解析文件。这意味着您将能够以特定的方式处理文件,从而获取您所关注的安全相关信息。
最后,编写代码的一部分工作是调试代码。能够解读错误信息以使您的代码正常运行,这一点非常重要。


我们将介绍常见的Python错误类型及其解决方法。总的来说,在完成本节学习后,您将对Python以及作为安全分析师如何运用它有更深入的理解。我迫不及待地想与您一同学习。
071:自动化在网络安全中的应用

在本节课中,我们将学习自动化在网络安全领域的重要性,并通过三个具体场景了解Python如何帮助安全分析师自动化日常任务,以提升系统安全性和监控效率。
概述:自动化是安全工作的核心 🔑
自动化是安全专业中的一个核心关注点。例如,监控每一次访问系统的尝试是非常困难的。因此,自动化实施的安全控制措施有助于将恶意行为者挡在系统之外。同时,自动化检测初始攻击活动也大有裨益。Python是实现自动化的绝佳工具。
接下来,让我们探索三个具体的应用示例。
示例一:实施数据库登录超时策略 ⏱️
上一节我们介绍了自动化的重要性,本节中我们来看看第一个具体应用场景。
想象你是一家医疗公司的安全分析师,该公司将机密病人记录存储在数据库服务器中。公司希望实施额外的控制措施来保护这些信息,以增强记录的安全性。你决定实施一个超时策略:如果用户花费超过三分钟登录数据库,则锁定该用户。这是因为,如果用户花费时间过长,可能是在尝试猜测密码。
为了实现这一点,你可以使用Python来识别用户何时输入了用户名,并开始计时,直到该用户输入正确的密码。
以下是实现该逻辑的一个简单代码框架:
import time
def monitor_login_time(username_entered_time, password_correct_time):
login_duration = password_correct_time - username_entered_time
if login_duration > 180: # 超过180秒(3分钟)
print(f"用户登录超时,账户已被锁定。")
# 此处添加锁定账户的实际操作代码
else:
print("登录成功。")
示例二:监控异常登录行为 🕵️
了解了登录超时监控后,我们来看一个更复杂的监控场景。
这次,想象你是一家律师事务所的安全分析师。最近发生了一系列持续的安全攻击,威胁行为者入侵员工账户并试图窃取客户信息,然后威胁要恶意使用这些信息。因此,安全团队正在努力解决所有允许攻击者侵入公司数据库的安全漏洞。你个人负责通过检查用户的登录时间戳、IP地址和登录地点来跟踪所有用户登录。
以下是需要标记的几种异常登录情况:
- 非工作时间登录:例如,用户在清晨时段登录。
- 非常规地点登录:用户从未被设定的两个工作区域之一登录。
- 并发登录:用户同时从两个不同的IP地址登录。
Python可以帮助你跟踪和分析所有这些不同的登录信息。
示例三:检测可疑的失败登录尝试 🚩
在监控了登录地点和时间后,我们最后来看看如何识别暴力破解等攻击模式。
想象你是一家大型组织的安全分析师。最近,该组织加强了安全措施,以确保所有面向客户的应用程序得到更好保护。由于访问这些应用程序需要密码,他们希望监控所有密码登录尝试,以发现可疑活动。

可疑活动的一个迹象是在短时间内出现多次失败的登录尝试。如果用户在最近30分钟内登录失败超过三次,你需要标记该用户。
在Python中实现此功能的一种方法是,解析一个包含所有用户对每台机器的登录尝试的静态TXT日志文件。Python可以结构化该文件中的信息,包括用户名、IP地址、时间戳和登录状态。然后,它可以使用条件语句来判断是否需要标记某个用户。
以下是一个简化的逻辑示例:
# 假设 log_entries 是一个包含字典的列表,每个字典代表一条日志记录
# 例如:{'username': 'user1', 'timestamp': '...', 'status': 'FAILED'}
failed_attempts = {}
for entry in log_entries:
if entry['status'] == 'FAILED':
user = entry['username']
failed_attempts.setdefault(user, []).append(entry['timestamp'])
# 检查每个用户在最近30分钟内的失败次数
for user, timestamps in failed_attempts.items():
recent_fails = count_recent_failures(timestamps, window_minutes=30)
if recent_fails > 3:
print(f"警告:用户 {user} 在30分钟内失败登录{recent_fails}次,已被标记。")
总结
本节课中我们一起学习了自动化在网络安全中的关键作用。我们通过三个具体示例——实施登录超时策略、监控异常登录行为以及检测可疑失败登录——探讨了Python如何帮助安全分析师自动化日常监控和防护任务,从而更高效地保护系统安全。这些只是安全分析师在日常工作中应用Python的少数几个例子。
072:持续学习与Python应用

概述
在本节课中,我们将跟随谷歌高级安全工程师Clancy,了解他如何在实际工作中应用Python,以及他对网络安全领域持续学习的见解。我们将学习Python在网络安全自动化中的重要性,并获取初学者入门与成长的实用建议。
正文
我的名字是Clancy,我是一名高级安全工程师。
我在谷歌的团队是持续保护谷歌敏感信息工作的一部分。
我们每天的工作都涉及保护客户数据和个人身份信息,每天的工作内容都不同。
这份工作让我能够运用不同的技能和知识体系,没有哪两天是完全一样的。
严格来说,我并非工程师或软件工程师出身;我实际上学的是会计。
亲身经历过任何类型的网络安全攻击,无疑会让你从对立面获得深刻的视角。
你能看到这如何影响用户,如何影响遭受攻击的人们。
如果我刚开始职业生涯时就了解网络安全领域究竟有多么广阔,那本可以让我探索更多方向。
Python是一种开发语言,我在谷歌的岗位上非常频繁地使用它。
关于Python,我最喜欢的一点是这门语言的能力。你可以用它创建非常强大的脚本,用于日常工作中。
当我最初学习Python时,最棘手的部分是学会如何用“Pythonic”的方式表达想法。
我利用了各种在线资源、书籍,并着手进行一些副业项目。
Python最大的优点之一是一门被广泛使用的语言,你可以根据你的技能水平,在网上找到非常多的资源。
Python以及任何其他开发语言都在不断进化。
持续承担项目,持续拓展你的知识,你就能持续成长。
我能给刚开始学习Python的人的建议是:让它变得有趣。我认为一旦你发现学习一门语言是有趣的,它就能让你更投入。
建立对网络安全是什么的良好基础认知。
在开始时让自己涉猎广泛一些,变得全面,然后从那里出发,你可以深入钻研你感兴趣的主题。
刚开始时可能会非常艰难,你会感觉像是在爬一座大山。
请坚持下去,持续学习,这最终会是一段非常有回报的经历。

总结
本节课中,我们一起学习了Clancy分享的宝贵经验。我们了解到Python在自动化网络安全任务中的强大能力,以及以“Pythonic”方式思考的重要性。更重要的是,我们认识到在广阔的网络安全领域,建立广泛基础后深入专研,并通过持续学习和实践项目来保持成长,是获得成功和满足感的关键。记住,让学习过程充满乐趣是保持动力的最佳方式。
073:在Python中访问文本文件 📄

在本节课中,我们将学习如何使用Python访问和读取文本文件。这是自动化处理日志文件等网络安全任务的基础步骤。
概述
网络安全专业人员经常需要审查日志文件。这些文件可能包含成千上万条记录,因此自动化这一过程会非常有帮助。这正是Python可以发挥作用的地方。我们将从导入一个仅包含几个单词的简单文本文件开始,然后在Python中将其存储为字符串。
使用 with 语句打开文件
要打开并读取文件,我们首先需要编写一个以关键字 with 开头的语句。with 关键字用于处理错误和管理外部资源。当使用 with 时,Python知道自动释放那些在程序运行结束前会占用系统资源的资源。在文件处理中,它常用于在读取文件后自动关闭文件。
以下是打开文件的基本语法结构:
with open(文件名, 模式) as 变量名:
# 在此处执行操作
open 函数详解
open 是Python中用于打开文件的函数。
- 第一个参数:这是您计算机上文本文件的名称,或者其在互联网上的链接。根据Python环境,您可能还需要包含此文件的路径。请记住在文件名中包含扩展名,例如
.txt。 - 第二个参数:此参数告诉Python我们想对文件做什么操作。在我们的例子中,我们想读取文件,因此使用字母
"r"(放在引号内)。如果我们想写入文件,则会将"r"替换为"w"。但这里我们专注于读取。 as关键字:as后面的变量(例如file)用于存储文件信息,只要我们在with语句块内,就可以使用它。
与其他类型的语句类似,我们以冒号 : 结束 with 语句。冒号后面的代码将告诉Python如何处理文件的内容。
读取文件内容
上一节我们介绍了如何用 with 语句和 open 函数打开文件。本节中我们来看看如何读取文件的内容。
在 with 语句块内,我们将使用Python内置的 read 方法。read 方法将文件内容转换为字符串。
与 for 循环类似,with 语句需要在下一行开始缩进,这告诉Python此代码在 with 语句块内执行。在语句块内,我们将使用 read 函数将文件转换为字符串,并将其存储在一个新变量中。这个新变量可以在 with 语句块外部使用。
以下是具体步骤:
- 输入
with语句打开文件。 - 在缩进块内,使用
.read()方法读取文件并赋值给一个变量。 - 退出
with语句块(取消缩进)。 - 打印该变量以查看文件内容。
让我们在Python中实践一下:
with open("update_log.txt", "r") as file:
text = file.read()
print(text)
完美,文本文件中的字符串被打印出来了。
总结

本节课中我们一起学习了在Python中访问和读取文本文件的基础知识。我们了解了如何使用 with open(...) as ...: 语句安全地打开文件,以及如何使用 .read() 方法将整个文件内容读取为一个字符串。这是自动化处理日志文件的第一步。
接下来,我们将讨论如何解析文件,以便将来能够处理安全日志。
074:解析Python中的文本文件


在本节课程中,我们将学习如何解析文本文件。解析是将数据转换为更易读格式的过程。我们将结合之前学到的列表和字符串知识,并学习一个新的字符串方法,来为导入Python的文本文件赋予结构,以便于后续分析。
概述:从导入到解析
上一节我们介绍了如何将文本文件导入Python。本节中,我们将更进一步,学习如何解析这些文本数据,使其结构化。这将使我们能够更轻松地分析数据。
什么是解析?🔍
解析是将数据转换为更易读格式的过程。在Python中,我们经常需要处理来自日志文件、报告等的原始文本数据。通过解析,我们可以将这些大块的文本分解成有意义的、可单独处理的部分。
关键工具:split()方法
为了实现解析,我们需要使用字符串的 split() 方法。这个方法可以将一个字符串转换成一个列表。
split() 方法通过基于指定的分隔符来分割字符串。如果不传递任何参数,则默认在遇到任何空白字符(包括空格、换行符等)时进行分割。
其基本语法如下:
字符串.split(分隔符)
例如,对于字符串 "We are learning about parsing.",使用 split() 方法:
text = "We are learning about parsing."
word_list = text.split()
print(word_list)
输出结果将是:['We', 'are', 'learning', 'about', 'parsing.']
我们使用 split() 方法将字符串分割成更小的片段,这比分析一大块文本要容易得多。
实战演练:解析安全日志
在本视频的示例中,我们将处理一个安全日志文件,其中每一行代表一个新的数据点(例如一个用户名)。我们的目标是将这些数据点存储到一个列表中。
由于Python将换行符视为一种空白字符,我们可以直接使用不带参数的 split() 方法来基于每一行进行分割。
以下是操作步骤:
首先,我们复用上一节视频中用于打开文件并将其内容读入字符串的代码。
with open(“update_log.txt”, “r”) as file:
text = file.read()
现在,让我们使用 split() 方法将这个字符串分割成列表,并打印输出。
print(text.split())
运行代码后,Python将输出一个用户名列表,而不是一个长长的、包含所有用户名的字符串。
如果我们需要保存这个列表以供后续使用,可以将其赋值给一个变量。
usernames = text.split()
print(usernames)
现在,usernames 这个列表就可以在其他代码中重复使用了。


总结与展望 🎉
恭喜你!你刚刚学会了在Python中解析文本文件的基础知识。我们了解了解析的概念,并掌握了使用 split() 方法将字符串转换为结构化列表的核心技能。
在接下来的视频中,我们将探索更多技术,帮助我们在Python中更深入地进行数据处理。


075:开发Python解析算法

在本节中,我们将整合之前学到的所有知识,学习如何导入文件、解析文件内容,并实现一个简单的算法来检测可疑的登录尝试。我们将创建一个程序,在每次新用户登录时运行,检查该用户是否有三次或更多次失败的登录尝试。
概述
我们将处理一个存储失败登录尝试的日志文件。该文件为TXT格式,每行包含一个用户名,每个用户名代表一次失败的登录尝试。我们的程序需要检查登录用户的用户名在该文件中出现的次数。如果次数达到或超过三次,程序将发出警报。
开发策略
首先,我们需要讨论输入数据的结构,以便制定程序开发策略。
我们的日志文件是一个TXT文件,其中每行包含一个用户名。每个用户名代表一次失败的登录尝试。因此,当用户尝试登录时,我们的程序需要检查其用户名在日志文件中出现的次数。如果该用户名重复出现三次或更多次,程序将返回警报。
导入与解析文件
我们将从导入日志文件、分割其内容并将其存储到变量中的代码开始。
以下是导入文件并存储用户名的代码:
with open('login_attempts.txt', 'r') as file:
usernames = file.read().splitlines()
让我们打印 usernames 变量以检查其内容:
print(usernames)
运行这段代码后,我们将得到一个用户名列表。这正是我们所期望的。现在,usernames 变量已准备好用于我们的算法。
设计计数算法
现在,让我们设计一个策略来统计列表中用户名的出现次数。我们将从用户名列表的前八个元素开始分析。
我们注意到,在列表中,用户名 eraab 出现了两次。但如何让Python来计数呢?我们将实现一个 for 循环来遍历每个元素。
我们可以用一个箭头来表示循环变量。同时,我们定义一个从0开始的计数器变量。
我们的 for 循环从用户名 elarson 开始。对于每个元素,Python会问:这个元素是否等于字符串 "eraab"?如果答案是“是”,计数器加一;如果“否”,计数器保持不变。
由于 elarson 与 eraab 不同,计数器保持为0。然后我们移动到下一个元素。我们遇到了第一个 eraab,此时计数器增加1。再移动到下一个元素,我们又发现一个 eraab,因此计数器再次增加1。这意味着我们的计数器现在为2。我们将对列表的其余部分继续这个过程。
在Python中实现算法
在Python中解决这个问题将涉及一个 for 循环、一个计数器变量和一个 if 语句。
让我们回到代码中。我们将创建一个函数来统计用户的失败登录尝试次数。
首先,定义我们的函数。我们将其命名为 login_check。它接受两个参数:第一个是 login_list,用于存储失败登录尝试的列表;第二个是 current_user,用于表示当前登录的用户。
在这个函数内部,我们首先定义计数器变量并将其值设置为0。
接下来,我们开始一个 for 循环。使用 i 作为循环变量,遍历 login_list。换句话说,随着循环迭代,它将直接遍历列表中所有的失败登录尝试。
在 for 循环内部,我们开始 if 语句。if 语句检查我们的循环变量是否等于我们正在搜索的当前用户。如果这个条件为真,我们希望给计数器加一。
我们的算法几乎完成了。现在,我们只需要最后的 if-else 语句来打印警报。如果计数器累计达到或超过三次,我们需要告诉用户他们的账户已被锁定,因此无法登录。我们还将为可以登录的用户编写一个 else 语句。
我们的算法现已完成。
测试函数
让我们在一个示例用户名上尝试我们的新函数。我们可以从列表中提取几个用户名,并对它们测试我们的函数。
首先,使用列表中的第一个名字进行测试:
login_check(usernames, 'elarson')
运行代码。根据我们的代码,该用户可以登录,因为他们的失败登录尝试次数少于三次。
现在,让我们回到用户 eraab。请记住,在我们失败登录尝试列表的前八个名字中,他们有两个条目。你认为他们能够登录吗?
当我们运行:

login_check(usernames, 'eraab')
我们得到了“账户锁定”的消息。这意味着他们有三次或更多次失败的登录尝试。干得漂亮!你刚刚开发了第一个涉及日志的安全算法。
随着你技能的增长,你将学习如何使这个算法更高效。但目前这个解决方案运行良好。
总结

在本视频中,我们整合了迄今为止学到的所有知识,从列表操作到算法开发,再到文件解析。我们在构建一个可应用于安全环境的算法的过程中完成了这一切。
076:调试策略 🐛

在本节课中,我们将学习如何识别和修复Python代码中的错误,即调试。作为一名安全分析师,阅读或编写代码是常见任务,而让代码正确运行往往是一大挑战。掌握调试技能至关重要。
概述
调试是识别和修复代码错误的过程。代码错误主要分为三类:语法错误、逻辑错误和异常。我们将逐一探讨每种错误类型及其调试策略。
语法错误
上一节我们介绍了调试的重要性,本节中我们来看看第一种错误类型:语法错误。语法错误涉及Python语言的无效使用,例如在函数定义后忘记添加冒号。
示例代码:
def greet_user(name)
print("Hello, " + name)
运行此代码会收到指示语法错误的消息。错误信息通常会包含错误位置,这使得修复相对容易,类似于纠正邮件中的简单语法错误。
以下是常见的语法错误示例:
- 省略函数名后的括号。
- 拼错Python关键字(如将
print写成prnt)。 - 未正确闭合字符串的引号。
逻辑错误
接下来,我们关注逻辑错误。逻辑错误可能不会导致程序崩溃或显示错误信息,但会产生非预期的结果。例如,在 print 语句中写错文本,或在条件判断中使用 < 而非 <=,这可能导致关键值被错误地排除。
为了诊断难以发现的逻辑错误,可以采用以下策略:
使用打印语句:
在代码的关键位置插入打印语句,用于描述代码执行到了哪个部分(例如 print("Line 20"))。通过观察哪些打印语句按预期输出,可以定位出问题的代码段。
使用调试器:
调试器允许你在代码中设置断点,从而将代码分段并逐段运行。这与打印语句的思路类似,通过独立运行各个部分来隔离问题。
异常
最后,我们来了解异常。异常发生在程序语法正确但无法执行某段代码时。例如,进行数学上不可能的操作(如除以零),或访问不存在的列表索引。
示例代码:
my_string = "security"
print(my_string[0]) # 输出 's'
print(my_string[1]) # 输出 'e'
print(my_string[100]) # 引发异常:IndexError: string index out of range
运行上述代码,前三个语句成功执行,但尝试访问索引100时,会抛出“字符串索引超出范围”的异常。对于异常,同样可以利用调试器和打印语句来定位潜在的错误源。

总结

本节课中我们一起学习了Python代码调试的三种主要错误类型:语法错误、逻辑错误和异常。我们探讨了各自的特征,并介绍了使用打印语句和调试器等策略来定位和修复问题。在Python编程中遇到错误和异常是正常的,关键在于掌握处理它们的方法,以确保编写的代码功能正常。
077:从错误中学习

概述
在本节课中,我们将跟随软件工程师Matt的分享,学习如何正确看待和处理编程与网络安全工作中的错误。我们将了解到,错误并非失败的标志,而是宝贵的学习机会。
从音乐到网络安全的旅程
上一节我们介绍了本课程的主题,本节中我们来看看Matt的个人经历。Matt在高中时梦想成为一名音乐家,专攻爵士长号。然而,他逐渐意识到乐队通常不会优先考虑长号手。与此同时,《黑客帝国》等电影激发了他对技术的兴趣,尽管电影情节并不完全反映真实的网络安全工作,但这种酷炫的形象为他提供了灵感。
重新认识编程错误
当我们开始学习编程时,常常会害怕错误。Matt最初也将代码错误视为自己能力不足的表现。但随着经验增长,他意识到每个人都会犯错,即使是最优秀的软件工程师也不例外。

关键在于转变视角:
- 错误是学习机会:错误提供了一个暂停和反思的契机,让你思考哪里出了问题。
- 错误是探索的起点:现在,Matt将错误视为深入了解问题、扩展计算机科学知识的时刻,这本身就是他工作的乐趣所在。
一个具体的错误案例:漏洞指纹识别
为了让大家更具体地理解,下面我们来看一个Matt在谷歌工作中遇到的棘手案例。在网络安全中,当发现一个系统漏洞后,如果后续又发现了相同的漏洞,安全团队不希望重复报告,以免给修复方造成困扰。
因此,他们采用了一种称为“指纹识别”的技术。其核心逻辑是:
if vulnerability.fingerprint == existing_fingerprint:
# 视为同一漏洞,不重复存储或处理
treat_as_duplicate()
else:
# 发现新漏洞,进行记录
store_new_vulnerability()
Matt当时遇到了一个难题:某些漏洞没有按他预期的方式进行指纹匹配。他花费了数周时间苦苦思索,试图找出问题根源。最终找到解决方案的那一刻,他感到了巨大的满足。
面对困难时的建议
在深陷问题泥潭时,自我怀疑很容易滋生。你可能会质疑自己的能力。Matt想对曾经的自己,也是对所有初学者说两点:
首先,困境并非没有尽头,总会找到出路。解决问题的成就感是无与伦比的。
其次,适时寻求帮助是完全可行的。Matt始终倡导在遇到困难时主动求助。大多数人都会乐于帮助你,尤其是面对复杂问题时。
总结
本节课中我们一起学习了如何以积极的心态看待编程和网络安全工作中的错误。我们从Matt的职业生涯转变中获得了启发,明白了错误是成长和学习的一部分。通过具体的“漏洞指纹识别”案例,我们看到了解决复杂问题后的成就感。最后,我们记住了两个重要建议:坚持终会突破,并且要勇于寻求帮助。网络安全领域日新月异,充满挑战与机遇,正是投身其中的好时机。
078:应用调试策略

在本节课中,我们将学习如何应用调试策略来修复一段存在问题的代码。我们将逐步识别并解决语法错误、异常和逻辑错误,最终确保代码按预期运行。
概述
我们将帮助同事调试一段代码,其功能是解析日志文件中的单行数据并返回结果。日志文件记录了软件应用的潜在问题,每行包含HTTP响应状态码、日期、时间和应用名称。代码需要跳过状态码为200(表示成功事件)的行,并返回无需解析的提示信息。
识别并修复语法错误
首先,我们需要运行代码以识别出现的错误。遇到的第一个错误是语法错误。
错误信息指出,语法错误发生在定义函数的那一行。函数定义的头部应以冒号结尾。我们添加冒号来修复此问题。
修复后,语法错误应消失。让我们再次运行代码。
处理名称异常
现在语法错误已修复,但我们遇到了另一个错误:名称错误。这是一种异常,意味着语法正确但Python无法处理该语句。
错误信息显示,解释器在将变量 application name 添加到解析列表时无法识别它。我们需要检查代码中该变量的定义部分。
问题在于变量名拼写错误。正确的变量名应为 application_name(包含下划线),而不是 applicationname。我们修正拼写。
修正后,再次运行代码。
检查并修复逻辑错误
现在,代码不再报错,但这并不意味着调试工作已完成。我们需要检查程序的逻辑是否按预期工作。
代码的输出是解析后的行。然而,根据需求,当状态码为200时,代码不应解析该行,而应打印“无需解析”的消息。但当前调用状态码为200时,并未显示此消息,这表明存在逻辑错误。
我们需要回到处理状态码200的条件语句部分进行调查。
为了定位问题,我们添加一些打印语句。我们在包含 return parse_list 的代码行前添加一个打印语句,在检查状态码是否为200的 if 语句前添加另一个,并在 if 语句内部再添加一个。
运行代码并查看打印输出。只有第一个打印语句有输出,另外两个没有。这说明程序甚至没有进入检查状态码200的 if 语句。
问题出在返回 parse_list 变量的代码行之前。当Python遇到第一个 return 语句时,它会立即退出函数,这意味着它在检查状态码是否为200之前就返回了结果。
为了修复这个问题,我们必须将检查状态码的 if 语句移到返回 parse_list 之前。
首先,我们删除之前添加的打印语句,以提高代码效率。然后,将 if 语句移到从行中解析出状态码的代码行之后。
现在,再次运行代码以确认问题已修复。代码成功打印了“成功事件,无需解析”的消息。

总结
本节课中,我们一起学习了应用调试策略。我们逐步修复了语法错误、名称异常和逻辑错误。通过添加打印语句定位问题,并调整代码执行顺序,最终确保了程序逻辑的正确性。希望这些策略能帮助你更有效地调试自己的代码。😊
079:章节总结

在本节课中,我们将回顾第七课的核心内容,重点总结在网络安全实践中应用Python的几个关键新主题。
回顾核心主题 🎯
上一节我们介绍了Python在网络安全中的基础应用,本节中我们来看看几个能帮助你将Python付诸实践的新主题。
首先,我们探讨了在Python中打开和读取文件。网络安全分析师需要处理大量日志文件,因此掌握这项技能至关重要。
接下来,我们讲解了文件解析。日志文件通常非常冗长。因此,构建这些文件的结构以使其更具可读性,有助于你自动化任务并获取所需信息。以下是读取文件的基本代码示例:
with open('logfile.txt', 'r') as file:
content = file.read()
最后,我们重点介绍了代码调试。了解如何调试代码可以为你节省大量时间,尤其是在代码复杂度增加时。调试的核心是定位并修复错误,其通用流程可表示为:
发现问题 -> 定位错误 -> 修复代码 -> 验证结果

总结与展望 📝
总的来说,希望你对在本节中完成的学习内容感到自豪。通过Python解决安全问题令人振奋,而我们所涵盖的知识将使你具备这种能力。

本节课中我们一起学习了文件操作、文件解析和代码调试这三个关键技能。这些是使用Python自动化处理安全日志和分析数据的基础,为你后续应对更复杂的网络安全任务做好了准备。
080:课程总结

在本节课中,我们将回顾整个课程的核心内容,总结在Python编程以及其在网络安全领域应用方面所学到的关键知识与技能。
🎓 课程回顾
随着本课程接近尾声,首先要祝贺你坚持学习了Python。探索这门在安全领域非常有用的编程语言,你应该感到很有成就感。
让我们简要回顾一下所学内容。
编程基础概念
首先,我们学习了Python的基本编程概念。我们讨论了变量、数据类型、条件语句和循环语句。这些主题为我们后续探索更深入的内容奠定了重要基础。
以下是我们在基础部分涵盖的核心概念:
- 变量:用于存储数据的容器。
- 数据类型:例如字符串(
str)、整数(int)、列表(list)。 - 条件语句:使用
if、elif、else来控制程序流程。 - 循环语句:使用
for和while来重复执行代码块。
编写高效代码
接下来,我们的重点是编写高效的Python代码。我们学习了如何在程序中复用函数以提高效率。我们探索了如何构建函数,甚至创建了自己的用户自定义函数。
另一个重要主题是模块和库。它们包含的预打包函数和变量可以让我们的工作变得更轻松。最后,我们学习了确保代码可读性的方法。
处理字符串与列表
在下一部分,我们专注于处理字符串和列表。我们学习了可应用于这些数据类型的多种方法。我们还了解了它们的索引,以及如何从字符串中切片字符或从列表中切片元素。
我们将所有这些知识结合起来,编写了一个简单的算法。然后,我们探索了如何使用正则表达式在字符串中查找模式。

Python实践应用
最后,我们以Python的实践应用作为课程的收尾。我们学习了如何打开、读取和解析文件。掌握这些技能后,你将能够处理在安全环境中遇到的各种日志文件。
我们还学习了如何调试代码。这是所有程序员都应掌握的一项重要技能。
🏆 总结与鼓励
你在这门课程中学到了很多关于Python的知识,做得非常出色。我希望不久之后,你能和我一起在安全专业领域中使用Python。
同时,我鼓励你多加练习,并随时可以重新观看这些视频。你对这些概念研究得越多,它们就会变得越容易。再次感谢你与我一同探索Python的世界。

浙公网安备 33010602011771号