【太原理工大学】软件系统安全—分析题

OK了,又是毫无准备的一场仗,我真是ありがとうございます 凸^o^凸

根据前几年传下来的信息,所谓“分析”,就是让你根据情节自行设计,例如如何设计表单等,这类多从实验中出,王老师强调好好做实验一定有他的道理。

实验一:漏洞分析实验

对于实验一我其实想不出来他会怎么考,索性就把实验顺一遍。但是百分之八十不会考这么细,时间紧张的同学可以把一跳了(反正看了也一知半解的,我也研究不透),直接看后面吧 (。ì _ í。)  

解释什么是栈溢出漏洞以及它如何被利用:

栈溢出漏洞是一种常见的软件安全漏洞,主要发生在使用C或C++等语言编写的程序中。这种漏洞是由于程序在处理输入数据时,没有正确地检查数据的长度,导致输入数据超出了预定的栈空间,覆盖了栈上的其他重要数据。

在实验报告中提到的例3-6中,如果程序没有正确处理输入数据,攻击者可以构造一个很长的字符串作为输入,这个字符串的长度超出了程序为其分配的缓冲区大小。当这个长字符串被复制到栈上的局部变量时,就会发生栈溢出。如果攻击者控制了溢出数据的内容,就可以覆盖栈上的返回地址,使得程序执行攻击者指定的代码。

函数栈结构分析:

例如本图带给我们的信息:

0018XXXX:0018开头的内存地址是Win7系统栈空间在VC6下的特征;

0xCCCCCCCC:函数局部变量初始化为一片0xCCCCCCCC,符合debug版的特性,这是编译环境为我们调试程序赋予的便利。有4片0xCCCCCCCC(如图),说明有4个函数。

栈底:18FF88、18FF48、18FED4、18FE74,貌似一串连续的栈底(如图),形成4个栈结构,且存在函数的嵌套调用,因为四个栈堆起来,如果不是嵌套调用,一个函数执行完毕,栈空间会释放掉,调用下一个函数时,栈还在原来的位置,就不会堆起来。

解释:栈帧是函数调用时在栈上分配的一块内存区域,包含了局部变量、参数、返回地址等信息。每个函数调用都会在栈上创建一个新的栈帧。根据提供的内存地址(例如18FF8818FF4818FED418FE74),我们可以看到这些地址是连续的,这表明它们可能是同一个栈的不同部分。如果存在多个连续的栈帧,这通常意味着有函数的嵌套调用。当一个函数调用另一个函数时,新的栈帧会在当前栈帧的顶部创建。

接下来,我们来看函数调用过程:

1.参数入栈
2.返回地址入栈
3.保存栈底
4.变量入栈
5.保存CPU环境

main函数:

1.参数入栈--------------------------------------01 00 00 00 B8 0F 2D 00 50 10 2D 00

2.返回地址入栈--------------------------------------B9 12 40 00

3.保存栈底--------------------------------------88 FF 18 00

4.变量入栈--------------------------------------42 CC CC CC --0A 00 00 00

5.保存CPU环境(/Zi 稳定保存12字节)-----00 00 00 00 00 00 00 00 00 E0 FD 7E

1.三个参数说明是main函数,命令行个数是1个,命令行字符指针数组和环境变量字符指针数组的首地址分别为0x002D0FB8和0x2D1050;

2.main函数返回地址是0x004012B9;

3.调用方栈底是0x0018FF88;

4.变量看形式有5个,1个int型0A 00 00 00(值为10),1个char型字符串68 65 6C 6C 00(内容为“hell”,00为字符串结束字符‘\0’),1个double型33 33 33 33 33 33 2F 40(值为15.6),1个float型00 00 28 41(值为10.5),1个char型0x42(值为‘B’);

5.当前CPU三个寄存器的值分别为0x7EFDE000、0x00000000、0x00000000。

从main函数自下至上,三个函数暂时称作fun1、fun2、fun3(先声明,再使用)。

fun 1函数:

fun 1被main调用

1.参数入栈--------------------------------------2C FF 18 00

2.返回地址入栈--------------------------------------02 11 40 00

3.保存栈底--------------------------------------48 FF 18 00

4.变量入栈--------------------------------------CD CC 5C 41 0A 00 00 00

5.保存CPU环境(/Zi 稳定保存12字节)------48 FF 18 00 00 00 00 00 00 E0 FD 7E

1.参数是0x0018FF2C,是指向main函数char型变量的地址,由此可以推断main函数的5个变量有可能是一个结构体的5个成员,否则,仅仅传地址要么造成后面的变量无意义,要么造成不合理的指针运算;

2.fun1函数返回地址是0x00401102;

3.fun1函数的调用方main函数的栈底是0x0018FF48;

4.变量有两个,1个int型0A 00 00 00(值为10),1个float型CD CC 5C 41(值是13.8f);

5.当前CPU三个寄存器的值分别为0x7EFDE000、0x00000000、0x0018FF48,此时fun1的栈顶被更新为其栈底保存的值。

第2、3个函数同理,2被1调用,3被2调用,一层套一层,直接上图

一个不严谨的方法:一片C为一块,信息都是从这一片C的前后得出的,前三组为保存CPU环境,后面几组main和调用函数有区别,自己看看。

实验二:SQL注入

本实验中最重要的就是一个SQL注入,至于前面安装配置小皮还有靶场什么的不说了

SQL的本质就是“故意写错填空内容”,将本来要输入的数据填写为代码,使得服务器向数据库的正常查询变成了不正常的代码执行,以此来达到入侵。

SQL 手工注入(非盲注)的基本步骤如下:
1)判断是否存在注入,注入是字符型还是数字型。
2)猜解 SQL 查询语句中的字段数及字段顺序。
3)获取当前数据库名。
4)获取数据库中的表名。
5)获取表中的字段名。
6)下载数据。

案例背景

假设你正在测试一个电子商务网站的安全性,该网站有一个搜索功能,允许用户通过用户名搜索用户信息。搜索框的URL参数如下:

http://example.com/search?username=[user_input]

步骤1:判断是否存在注入

首先,需要确定目标应用是否存在SQL注入漏洞,并判断注入类型(字符型或数字型)

字符型注:输入 `'`(单引号)导致查询失败或出现异常(你输入的数据其实是作为SQL查询语句提交给数据库的,加一个单引号后会将原本的查询语句打乱,导致报错)。

数字型注入:输入特殊字符或SQL语句片段,如 `1' or '1'='1`,如果返回结果与预期不符,可能存在注入(通过1=1这个恒等式(不是1==1,SQL中语法与C不一样)来使or这条语句判断为真,以达到侵入的目的)。

步骤2:猜解字段数及字段顺序

通过SQL注入点,尝试改变查询结果的排序,来确定SQL查询中涉及的字段数量和顺序。

输入以下字符串来确定查询语句中的字段数:

1' order by 1 --+
//如果页面正常显示,增加数字直到出现错误,比如:
1' order by 3 --+  //如果页面出错,说明查询语句涉及3个字段
// 在语法上--会使之后的语句变成注释,由此破坏查询命令

步骤3:获取当前数据库名

利用SQL注入点,尝试获取当前数据库的名称

' union select database() --+

步骤4:获取数据库中的表名

在确认了数据库名后,下一步是获取数据库中包含的表名

' union select table_name from information_schema.tables where table_schema='[target_db_name]' --+
//这里的[target_db_name]是你要入侵的数据库名字,同样使用--+使后面的语句变成注释,不影响你的“入侵”

步骤5:获取表中的字段名

确定表名后,可以进一步获取表中各字段的名称。

' union select column_name from information_schema.columns where table_name='[target_table_name]' --+
//[target_table_name]是实际的表名,你想康康那一列就康哪一列(。ì _ í。)

步骤6:下载数据

最后一步是尝试获取敏感数据,如用户名和密码

' union select user, password from [target_table_name] --+
//裤衩子都给他看光

实验三:登陆界面的需求分析

如果是前面的实验是在讲“攻”,那这个实验就是在说“防”了,怎样的设计可以提高软件的安全性

首先登陆页面是必不可少的,由此也就延伸出了本实验所讨论的内容。

邮箱注册登录方式

  • 优点:免费、方便、安全、多功能。
  • 缺点:垃圾邮件、邮箱泄露风险、容量限制。
  • 验证方式:用户名和密码、邮箱验证码、手机短信验证、安全问题验证。

手机号注册登录方式

  • 优点:方便快捷、安全性高、信息真实性高。
  • 缺点:依赖手机网络、隐私泄露风险、无法记住账号。
  • 验证方式:短信验证码、语音验证码、手机号验证链接。

传统账号密码登录

  • 优点:安全性高、稳定性好、用户习惯。
  • 缺点:操作繁琐、容易忘记密码、安全性不足。

根据实验报告中的登录界面需求分析,以下是可能存在的一些软件安全漏洞:

1. **注入漏洞**:
   - 如果输入未经适当过滤,攻击者可能会利用SQL注入或命令行注入攻击来操纵数据库查询或执行恶意命令。

2. **跨站脚本攻击(XSS)**:
   - 如果用户输入数据(如用户名或密码)未经适当处理就显示在网页上,可能会引起存储型或反射型XSS攻击。

3. **暴力破解**:
   - 如果系统没有有效的防暴力破解措施,如登录尝试次数限制或验证码,攻击者可能会尝试无限次登录来猜测密码。

4. **密码安全问题**:
   - 如果密码策略不够强,允许用户设置简单密码或不要求密码复杂度,密码容易被破解。

5. **信息泄露**:
   - 如果用户信息(如密码、身份证号等)未经加密存储或传输,可能会在传输过程中或存储时被窃取。

为了保障实现注册和登录功能时对用户信息及相关数据的保护,在设计时必须实现以下功能点。(4-6点)

  1. 安全漏洞修复:系统必须及时修复已知的安全漏洞,以保障用户信息的安全。同时,系统必须定期进行安全检查和漏洞扫描,及时发现并修复潜在的安全问题。

2. 防暴力破解策略:系统必须设置防暴力破解策略,例如限制用户登录次数、增加验证码等,以防止恶意攻击者通过暴力破解获取用户信息。

3. 用户信息传输加密:用户在注册或登录时,输入的信息必须经过加密处理后再传输到服务器,以防止信息被窃取或篡改。

4. 用户信息加密存储:用户的敏感信息(如密码、身份证号等)必须经过加密处理后再存储到数据库中,以防止数据泄露和恶意攻击。

实验四:编写正则表达式

正则表达式(RegEx)是一种文本模式,包括普通字符和特殊元字符,用于匹配制定规则的字符串。编译器中的词法分析器会使用正则表达式去匹配代码中的关键字,网站上的注册表单会用他去判断密码的强弱,在爬虫中同样有用。

正则表达式实例:

  1. 用户名验证:必须字母开头,6~16位,包含字母、数字和其他字符。
  2. 密码验证:8-16字符,必须包含数字、字母和其他字符。
  3. 强密码验证:16-24字符,不能有连续数字,包含数字、字母和其他字符。
  4. 身份证号验证:18位,最后一位可以是数字或X。
  5. E-mail地址验证:包含用户名和域名,支持字母、数字、下划线、短横线和点号。
  6. 电话号码验证:11位,开头必须是1,全数字。
  7. IP地址验证:四组数字,每组0~255,用点分隔。
  8. 中文字符验证:字符串必须全是汉字。
  9. 域名验证:字母或数字开头,可含中划线,后缀至少两个字符。
  10. 数字验证:匹配整数或小数。

现在来介绍正则表达式的规则:

1.used?  //?是一个特殊字符,表示?前的字符可有可无,例如本例可以匹配到used,也可以匹配到use
2.ab*c  //*代表前面的字符可以出现0次获多次,例如本例可以匹配到ac,abc,abbbbbc
3.ab+c  //+会匹配出现一次及以上的字符,例如abc,abbbc
4.ab{6}c  //比+更精确,能够匹配出现了六次的字符,abbbbbbc,这种写法还可以是{2,6}2到6次之间,{2,}两次以上等
5.a(cat|dog)  //或限定符,匹配到a cat,a dog
6.[abc]+  //方括号要求匹配的字符只能取自于他们,比如abcc,cacb,bbc
7.[a-z] //所以小写字符
  [a-zA-Z] //所有英文字符
  [a-zA-Z0-9]  //所有英文字符和数字
8.[^0-9]  //^代表所有非括号内的字符,本例中表示所有非数字字符,包括换行符

同时,正则表达式还规定了很多元字符,这里不多赘述了,想看的自己下去了解吧。

来看两个简单实例:

1.颜色值匹配

2.IPv4地址匹配

好了,至此,四篇实验全部讲完,我们来进入实战。

实战1:给你一段代码问你代码相关的东西(相关实验2,3)
// 假设的PHP代码,用于从数据库检索用户信息
if (isset($_POST['username'])) {
    $username = $_POST['username'];
    // 构造SQL查询
    $query = "SELECT * FROM users WHERE username = '$username' AND password = '" . md5($_POST['password']) . "'";
    // 执行查询
    $result = mysqli_query($conn, $query);
    // ...
}

问可能受到的攻击和防范措施:

可能的攻击方法:

  1. SQL注入

    • 攻击者可以通过在username输入框中输入如' OR 1=1 --,绕过登录验证,因为SQL查询没有进行适当的转义或使用参数化查询。
  2. 密码绕过

    • 如果攻击者发现密码字段的MD5值总是相同,他们可能会尝试使用这个值来绕过密码验证。

避免攻击的基本对策

  1. 使用预处理语句

    • 使用预处理语句和参数化查询,确保用户输入作为参数处理,而不是作为SQL代码的一部分。
  2. 输入过滤和验证

    • 对所有输入进行严格的过滤和验证,确保它们不包含潜在的恶意代码。
  3. 密码存储安全

    • 不要使用MD5存储密码,因为它不安全且容易受到彩虹表攻击。使用更强的哈希函数,如bcrypt。

此类题其实就是考察你对这门课教过的各种攻击记忆有多少,有哪些种类的攻击,是通过什么原因导致的。(对于此,我个人认为其实不算是分析,而更像是简答,把你记住的攻击全往上怼就行了。考试卷面有限,不会把完整代码都给你写出来的,既然有省略,我们就可以钻空子,最常见的就是SQL注入攻击,再其次就是XSS,你能说他省略的地方一定没有用户输入回显的方法吗?既然有,那就很有可能存在XSS漏洞。诸如此类,所以这题更看重的是你心态稳不稳,看不懂也别慌)

对于易受SQL注入攻击的Web应用程序,可能的攻击方法包括但不限于以下几种

1. **经典SQL注入**:
   - 攻击者通过输入特殊的SQL代码片段,尝试改变原有查询逻辑,获取、篡改或删除数据库中的敏感数据。(看到输入的内容直接作为查询语句的,不用想,SQL注入

// 直接将用户输入拼接到SQL查询中,易受SQL注入攻击
if (isset($_POST['username']) && isset($_POST['password'])) {
    $username = $_POST['username'];
    $password = $_POST['password'];
    $query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
    $result = mysqli_query($conn, $query);
    // ...
}

2. **XSS跨站脚本攻击**:
   - 用户输入直接输出到页面,没有进行HTML编码,易受XSS攻击。(看到有输入回显相关的,OK,XSS

// 假设的PHP代码,用于显示用户输入的评论
echo "Welcome, " . $_GET['name'] . "!";

3. **不安全的文件上传**:
   - 直接使用用户上传的文件名,可能包含相对路径或特殊字符,易导致文件权限提升或敏感文件覆盖。(看到文件看到file了,可能会有不安全的文件上传

// 假设的PHP代码,用于处理文件上传
if ($_FILES['file']['error'] == 0 && $_FILES['file']['size'] <= 1024 * 1024 * 5) {
    if (move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name'])) {
        echo "File uploaded successfully.";
    } else {
        echo "File upload failed.";
    }
}

4. **不安全的直接对象引用**:
   - 用户ID直接用于查询,易受不安全的直接对象引用攻击。(和SQL注入差不多,要查那个直接就查了,可能会出现不安全的直接对象引用

// 假设的PHP代码,用于显示用户配置文件
$user_id = $_GET['user_id'];
$query = "SELECT * FROM user_profiles WHERE id = $user_id";
$result = mysqli_query($conn, $query);
// ...

5. **文件上传漏洞利用**:
    - 如果SQL注入漏洞存在于文件上传功能中,攻击者可能会上传恶意文件来执行代码。

6. **远程命令执行**:
    - 在某些情况下,SQL注入可能被用来执行操作系统命令,导致远程命令执行。

### 防御措施:
- **使用预处理语句和参数化查询**:避免直接将用户输入拼接到SQL语句中。
- **输入验证和过滤**:确保所有输入都符合预期格式,过滤掉潜在的危险字符。
- **最小权限原则**:数据库账号应具有执行必要操作的最小权限。
- **错误处理**:不要向用户展示详细的数据库错误信息。
- **定期安全审计**:定期对应用程序进行安全审计,检查潜在的安全问题。

通过这些措施,可以显著提高应用程序的安全性,减少被SQL注入攻击的风险。

好了,这类题就是这样,其中SQL和XSS比较重要,剩下几个随便吧,大概写点就有几分呢,别放弃 (。ì _ í。)

实战2:给你一个登陆页面回答相关问题(关联实验3)

既然实验做了登陆页面的分析,那大题应该会考一个登陆页面相关的。其实本质来说跟上一道差不多,也是记住了可能有哪些漏洞,看图说话罢了。

首先根据实验,来看三种登陆方式可能出现的问题,这是最有可能得分点:

电子邮件登录、手机号码登录和账号密码登录是常见的登录方式,每种方式都有其潜在的安全问题:

### 电子邮件登录可能存在的问题:

1. **电子邮件被截获**:
   - 使用电子邮件进行通信时,如果未加密,邮件内容可能在传输过程中被截获。

2. **电子邮箱被非法登录控制**:
   - 邮箱账户若被攻破,攻击者可能获取用户的登录令牌或其他敏感信息。

3. **电子邮件系统被攻击控制**:
   - 电子邮件服务提供商若存在安全漏洞,可能被攻击者控制,影响所有用户。

4. **针对特定用户的电子邮件社会工程学攻击**:
   - 通过发送欺诈性邮件,诱导用户泄露密码或其他敏感信息。

5. **Cookie和Session的安全性问题**:
   - 如果Session ID存放在Cookie中,并且没有适当的安全措施,可能遭受CSRF攻击。

### 手机号码登录可能存在的问题:

1. **依赖手机网络**:
   - 如果用户在没有网络的情况下,可能无法接收验证码,影响登录。

2. **隐私泄露风险**:
   - 使用手机号码作为登录凭证可能会增加个人信息泄露的风险。

3. **短信服务被攻击**:
   - 短信服务若被攻击者截获或篡改,验证码可能被拦截。

4. **手机设备安全**:
   - 手机若被植入恶意软件,可能影响登录安全。

### 账号密码登录可能存在的问题:

1. **密码强度不足**:
   - 用户可能使用弱密码,容易被猜测或通过暴力破解手段破解。

2. **密码存储安全**:
   - 如果服务器端未对密码进行加密或使用不安全的哈希算法,密码可能被泄露。

3. **键盘记录器攻击**:
   - 恶意软件可能记录用户的键盘输入,从而获取账号密码。

4. **暴力破解攻击**:
   - 攻击者可能尝试多次登录,猜测密码。

5. **社交工程攻击**:
   - 通过诱导用户提供密码或其他敏感信息。

所以,第一步先看题干,如果是账密登陆,就可以答密码强度、密码存储等问题;邮箱就是截获、非法控制这种;手机也是一个道理。

其次,还有可能出现:

  1. 弱密码策略:如果系统允许用户设置简单或弱密码,那么账户容易被暴力破解。

  2. 缺乏双因素认证:如果没有提供双因素认证选项,就会增加账户被入侵的风险。

  3. 会话管理不足:如果有“多长时间内免密登陆”这种,系统可能提供长时间有效的会话,这可能使会话劫持更加容易。

  4. 输入验证不足:如果登录表单没有正确验证输入,可能会受到SQL注入、跨站脚本(XSS)等攻击。这也跟上一题说的对上了。

  5. 信息泄露:如果有管理员入口,如果存在漏洞,可能会泄露管理员账户信息。

  6. 扫码登录的安全性:如果有扫码登录功能,可能会受到中间人攻击或其他安全威胁。

通用的安全措施:

  • 使用HTTPS:确保所有通信都是加密的,防止数据在传输过程中被截获。
  • 多因素认证:增加安全层次,即使密码被破解,攻击者也难以获取账户控制权。
  • 限制登录尝试次数:防止暴力破解攻击。
  • 安全的密码策略:强制使用强密码,并提供密码管理建议。
  • 安全的Cookie使用:设置HttpOnly和Secure标志,防止CSRF和XSS攻击。
  • Session管理:定期轮换Session ID,并在用户登出时使Session ID失效。
  • 双因素认证:通过短信验证码、身份验证器应用或硬件令牌提供第二层安全验证。
  • 教育用户:提高用户对钓鱼攻击和社交工程攻击的认识。
  • 定期安全审计:检查和修复安全漏洞,更新安全策略。

通过实施这些安全措施,可以显著提高登录系统的安全性,减少被攻击的风险。

实战3:缓冲区溢出,栈相关(相关实验1)

实验一能考的我认为只有溢出一个点了,可能还夹杂着一些密码安全相关的东西。话不多说,直接看题。

#include <stdio.h>
#include <string.h>

int main() {
    char password[20] = "mysecurepassword";
    char input[20];
    printf("Enter your password: ");
    
    // 危险:使用gets()可能导致缓冲区溢出
    gets(input); // 危险函数,已被废弃

    if (strcmp(input, password) == 0) {
        printf("Access granted.\n");
    } else {
        printf("Access denied.\n");
    }
    
    return 0;
}

此C语言程序片段,用于从用户那里获取输入并检查是否与预设密码匹配:

可能出现的问题:

  1. 缓冲区溢出: 使用gets()函数读取用户输入会导致未定义行为,如果输入超过input数组的大小,将覆盖相邻内存区域,可能导致程序崩溃或安全漏洞。

  2. 不安全的密码存储: 密码以明文形式存储在源代码中,这使得密码对所有可以访问源代码的人来说都是可见的。

  3. 不安全的密码输入: 使用gets()函数无法防止用户输入带有换行符的长字符串,增加了溢出风险。

  4. 密码猜测: 如果程序在比较密码时反馈具体是哪个部分不正确(如长度或内容),攻击者可以使用此信息进行猜测。

  5. 缺乏加密措施: 密码在内存中以明文形式存在,如果程序的内存被dump,密码同样会暴露。

  6. 不健壮的输入处理: 程序没有检查gets()是否成功读取输入,没有错误处理机制。

  7. 过时的函数使用gets()函数由于其不安全性,在C11标准中已被移除,使用此函数的代码不符合现代C语言标准。

解决对策:

  1. 使用安全的输入函数: 使用fgets()代替gets(),并检查返回值以确保成功读取。

    fgets(input, sizeof(input), stdin);

  2. 限制输入长度: 在将输入与密码比较之前,确保去除字符串末尾的换行符,并检查长度。

  3. 安全地存储密码: 使用加密哈希存储密码,而不是明文。

  4. 使用恒定时间比较: 使用如timingsafe_bcmp()这样的函数比较密码,以防止侧信道攻击。

  5. 错误处理: 对所有用户输入和程序逻辑进行错误检查,并适当处理异常情况。

  6. 遵循现代编程实践: 遵循C语言的最佳实践和现代编程标准,避免使用过时和不安全的函数。

  7. 代码审查和安全测试: 定期进行代码审查和安全测试,包括静态分析和动态分析,以发现潜在的安全问题。

这种类型的题目通常考察对C语言编程中常见安全漏洞的理解和防御策略,包括但不限于缓冲区溢出、不安全的输入处理、密码安全、内存安全等凸^-^凸

实战4:正则表达式编写

这个其实有点难,不是死记硬背能解决的了,可能上考场后一个点没有想到就答不出标准答案,不过做不到和标准答案一摸一样,大差不差还是可以的。限定小写字母会写吧,限定数字会写吧,限定出现几次会写吧,把会写的写写就行

背景: 在开发一个用户注册功能时,需要验证用户输入的邮箱地址是否有效。为了确保用户填写的邮箱符合标准的格式,你需要编写一个正则表达式来验证邮箱地址。

要求: 编写一个正则表达式,满足以下条件:

  1. 邮箱地址以字母、数字、下划线、短横线或点开始。
  2. 必须包含一个@符号,@符号前后可以有字母、数字、下划线、短横线或点。
  3. 域名部分至少要有一个点,点的两侧可以有字母、数字。
  4. 不能以点或短横线开始或结束。
  5. 邮箱地址长度应在3到255个字符之间。

示例:

  • 有效的邮箱:example_user@mail服务商.com
  • 无效的邮箱:user@.comuser@.com.cnuser@.com.user@服务商.com

任务: 请根据以上要求编写一个正则表达式,并说明每个部分的作用。

答案:

^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

^:匹配字符串的开始。

[a-zA-Z0-9._-]+:匹配一个或多个字母、数字、下划线、点或短横线。

@:字面意义上的@符号。

[a-zA-Z0-9.-]+:匹配一个或多个字母、数字、点或短横线(域名部分)。

\.:字面意义上的点,因为点在正则表达式中是一个特殊字符,所以需要使用反斜杠进行转义。

[a-zA-Z]{2,}:匹配两个或更多的字母(顶级域名)。

$:匹配字符串的结束。

上一届似乎还考了“谈谈你这学期做过的实验和心得体会这种题”,大有“你这学期的任课老师叫什么名字”的感觉,四个实验咱们之前都说过,这里不再赘述。选择题应该是把上一篇总结的知识点挖空变成选择,难度不大,看过上一篇的能答个七七八八。至此,本科考试知识点全部讲解完毕。

之后如果想到能够补充的会继续发,可以订阅一下专栏。

稳住心态,不要慌,结课考试而已,总有人要过,为什么不能是认真准备了的各位呢?把前面的简答认真看了,胜利必然

英国优秀法学生祝您考试顺利

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/711990.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自然抽样和平顶抽样

自然抽样和平顶抽样是两种信号处理和采样技术&#xff0c;它们在音频信号处理、信号重建以及数字信号处理中有着不同的应用。 1. 自然抽样&#xff08;也称为理想抽样或无失真抽样&#xff09;&#xff1a;样值脉冲的幅度随原始信号m(t)的幅度而变&#xff1b; 自然抽样过程的…

个人网站制作 Part 26 添加在线日历功能 | Web开发项目添加页面缓存

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 添加在线日历功能&#x1f528;使用日历服务&#x1f527;步骤 1: 选择日历服务&#x1f527;步骤 2: 安装FullCalendar&#x1f527;步骤 3: 创建FullCalendar组件&…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 生成哈夫曼树(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 生成哈夫曼树(100分) 🌍 评测功能需要订阅专栏后私信联系清…

数据中心布线管理:预标记线缆与移动扫描技术的融合

随着信息技术的飞速发展&#xff0c;数据中心布线管理面临着前所未有的挑战。传统的布线管理方式已无法满足现代数据中心高效、准确和可靠的需求。在这样一个背景下&#xff0c;预标记线缆与移动扫描技术的结合&#xff0c;为数据中心布线管理带来了革命性的解决方案。 布线管理…

基于System-Verilog点亮LED灯

文章目录 一、System-Verilog介绍1.1System-Verilog 二、简单的语法介绍2.1接口实例2.2全局声明和语句实例2.3时间单位和精度2.4用户定义的类型2.5 枚举类型 三、流水灯参考 一、System-Verilog介绍 1.1System-Verilog SystemVerilog是一种硬件描述和验证语言&#xff08;HDV…

stm32f103 HAL库 HC-SR04测距

目录 一、实现测距二、添加TIM3控制LED根据距离以不同频率闪烁三、观察时序Modebus协议12路超声波雷达设计方案1. 系统架构设计2. 硬件设计3. 软件设计4. 通信协议设计5. 用户接口6. 安全和冗余7. 测试和验证8. 电源和物理封装9. 文档和支持 一、实现测距 配置时钟 配置定时器…

八、BGP

目录 一、为何需要BGP&#xff1f; 二、BGP 2.1、BGP邻居 2.2、BGP报文 2.3、BGP路由 2.4、BGP通告遵循原则 2.5、BGP实验 第一步&#xff1a;建立邻居 第二步&#xff1a;引入路由 BGP路由黑洞 路由黑洞解决方案 1、IBGP全互联 2、路由引入 3、MPLS 多协…

【Python】数据处理:Matplotlib绘图

Matplotlib是Python强大的数据可视化工具库&#xff0c;类似于MATLAB语言。Mat-lotlib提供了一整套与MATLAB相似的命令API&#xff0c;十分适合进行交互式制图&#xff0c;而且也可以方便地将它作为绘图控件&#xff0c;嵌入GUI应用程序中。 Matplotlib是神经生物学家John D.Hu…

轻松拿捏C语言——【关机代码】

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 我们可以通过写…

c++编程(16)——STL(4)deque

欢迎来到博主的专栏&#xff1a;c编程 博主ID&#xff1a;代码小豪 文章目录 dequedeque的优劣势deque的操作constructor元素访问 deque deque的全称是double ended queue&#xff0c;译为双端队列&#xff0c;如何理解这个双端呢&#xff1f;我们以vector为例&#xff0c;vec…

深入剖析人才管理的关键要素:“选、用、育、留”四大核心要素

在当今这个日新月异的商业时代&#xff0c;企业的成功不再仅仅取决于资金、技术或市场策略&#xff0c;而更多地依赖于企业所拥有的人才资源。有效的人才管理策略&#xff0c;尤其是“选、用、育、留”四大核心要素&#xff0c;已成为推动企业持续发展的关键。 一、选&#xff…

Canvas绘制老友记时钟

Canvas绘制老友记时钟 前言 一直做3D/2D可视化&#xff0c;Canvas API和三角函数&#xff0c;空间几何是基础。在官网上看了一遍Canvas API之后&#xff0c;决定绘制一个老友记时钟来巩固知识点&#xff0c;本文用实际代码讲解绘制过程。 代码 HTML <canvas id"myC…

electron模板【lectron-react-boilerplate】多窗口配置【HtmlWebpackPlugin】多页面配置

如果您正在使用electron-react-boilerplate进行快速的Electron应用程序开发,您可能会遇到想要在桌面应用程序中拥有多个原生窗口的情况。 MacOS窗口图像由OpenClipart-Vectors提供,来源Pixabay。 开始之前需要提及的事情! Electron有一个主进程和渲染进程的模式。可以有多个…

【MySQL】聊聊数据库是如何保证数据不丢的

对于一个存储系统来说&#xff0c;其中比较关键的核心组件包含&#xff0c;网络、存储模型、持久化、数据结构等。而数据如何保证不丢失&#xff0c;对于不同的存储系统来说&#xff0c;比如Redis采用AOF和RDB的方式进行混合使用&#xff0c;而MySQL采用日志进行保证。也就是re…

【C++11】第一部分(一万六千多字)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 C11简介 统一的列表初始化 &#xff5b;&#xff5d;初始化 std::initializer_list 声明 auto decltype 右值引用和移动语义 左值引用和右值引用 左值引…

车票信息的请求与显示

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 1 发送与分析车票信息的查询请求 得到了获取车票信息的网络请求地址&#xff0c;然后又分析出请求地址的必要参数以及车站名称转换的文件&#xff…

利用鱼骨图进行项目问题复盘与改进

一、引言 在项目管理中&#xff0c;问题复盘是一个至关重要的环节。它不仅能帮助我们识别项目执行过程中出现的问题&#xff0c;还能促使我们深入探究问题的根本原因&#xff0c;从而采取有效的改进措施。在这个过程中&#xff0c;鱼骨图作为一种强大的工具&#xff0c;为我们…

GiantPandaCV | 提升分类模型acc(三):优化调参

本文来源公众号“GiantPandaCV”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;提升分类模型acc(三)&#xff1a;优化调参 一、前言 这是本系列的第三篇文章&#xff0c;前两篇GiantPandaCV | 提升分类模型acc(一)&#xff1a;B…

一文讲通:前后端分离的四种开发模式,及其优缺点。

前后端分离已经成为了开发的主流模式&#xff0c;很多老铁认为前后端分离就是各干各的&#xff0c;其实不然。 前后端分离有多种模式&#xff0c;贝格前端工场为大家一一详解。 1. 前后端完全分离 在这种模式下&#xff0c;前端和后端是完全独立的两个系统。前端使用一种框架…

Python学习笔记9:入门知识(九)

缩进 什么是缩进&#xff1f; 缩进&#xff0c;简单的理解为本行的首字符相比上一行的首字符位置相对靠后。目前笔者接触的编程语言缩进一般是4字符&#xff0c;直接可以按tab键就行。 为什么突然讲缩进&#xff1f; Python这门语言&#xff0c;是依靠缩进来判断当前行与上…