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

DVWA靶场保姆级通关教程--03CSRF跨站请求伪造

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 目录

    文章目录

    前言

    一、low级别的源码分析

    二、medium级别源码分析

    安全性分析

    增加了一层 Referer 验证:

    关键点是:在真实的网络环境中,攻击者并不需要(也不可能)拦截或修改用户的请求

    常见诱导方式

    1. 自动提交表单(伪装成广告或页面跳转)

    2. 隐藏在图片标签中(GET 请求时)

    3. 模拟跳转页面 

    攻击者利用的是:

    三、high级别源码分析

    当前 High 级别 CSRF 防御机制:

    也就是说:

    附加说明(常见误区):

    四、impossible级别源码分析

    1. 引入了 CSRF Token 校验

    2. 使用了预处理语句(Prepared Statements)

    3. 增加了密码确认机制

    4. 错误处理和反馈更加清晰

    5. 密文加密

    6. 会话令牌(Session Token)管理

    总结


前言

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的Web安全攻击方式。它的核心思想是:

攻击者诱导用户在已经登录认证的情况下,发起一个伪造的请求到受信任的网站,从而在用户不知情的情况下完成一些恶意操作。

图示如下:


提示:以下是本篇文章正文内容,下面案例可供参考

一、low级别的源码分析

<?php// 如果用户提交了 Change 参数(通过 GET 请求)
if( isset( $_GET[ 'Change' ] ) ) {// 获取新密码和确认密码的值$pass_new  = $_GET[ 'password_new' ];     // 新密码$pass_conf = $_GET[ 'password_conf' ];    // 确认密码// 检查两次输入的密码是否一致if( $pass_new == $pass_conf ) {// 如果一致,则进行下一步处理// 对新密码进行 SQL 转义,防止 SQL 注入(不过这里写法比较老旧)$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// 使用 MD5 对密码加密(不安全,但这是示例)$pass_new = md5( $pass_new );// 构造 SQL 更新语句,将当前用户的密码更新为新密码$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";// 执行 SQL 更新操作$result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );// 给用户的提示信息:密码修改成功echo "<pre>Password Changed.</pre>";}else {// 如果密码不一致,提示错误echo "<pre>Passwords did not match.</pre>";}// 关闭数据库连接((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}?>

这里虽然修改密码失败,但是可以通过URL发现,修改密码的操作是通过get传参提交了一个change的请求,打开一个新的页面直接在地址栏修改,前提是打开一个新的页面发现用户并没退出登录,类似点击了一个a(img)(form)标签跳转到一个新的页面,使用这个已登录用户的session信息进行验证

在新的标签构造修改密码的URL如下:

  • 修改密码使用 GET 请求(不安全)。

  • 用户已登录,浏览器会自动带上 Cookie。

  • 所以即使在新窗口点击链接打开,只要用户没退出登录,就会生效。

  • 攻击者就能通过构造 URL + 诱导点击,悄悄修改密码。

二、medium级别源码分析

<?php// 判断用户是否提交了 GET 参数 Change
if( isset( $_GET[ 'Change' ] ) ) {// 验证请求是否来自本站,即检查 Referer 是否包含当前服务器域名if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {// 获取用户输入的新密码和确认密码$pass_new  = $_GET[ 'password_new' ];$pass_conf = $_GET[ 'password_conf' ];// 检查两次输入是否一致if( $pass_new == $pass_conf ) {// SQL 过滤 + MD5 加密(仍然不安全,仅用于演示)$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$pass_new = md5( $pass_new );// 执行 SQL 更新语句$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";$result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );// 显示提示信息echo "<pre>Password Changed.</pre>";}else {// 密码不一致,报错echo "<pre>Passwords did not match.</pre>";}}else {// 如果 Referer 不可信,拒绝请求echo "<pre>That request didn't look correct.</pre>";}// 关闭数据库连接((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}?>

安全性分析

增加了一层 Referer 验证:

Referer(HTTP 头部的一部分) 是浏览器在发起请求时自动携带的信息,用于告诉服务器:

“这个请求是从哪个页面跳转过来的”。

if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )
  • 作用:防止来自第三方页面(例如攻击者网站)的请求。

  • 原理:合法请求应来自当前站点的页面,Referer 会包含本站域名。

  • 攻击者如果在自己的页面发起请求,Referer 通常不会包含受害网站域名,因此会被拦截。

这里如果还是用low级别的方法在一个新的页面构造修改密码的请求,会报错。主要就是referer的参数没有和第一个请求的时候保持一致,那么先正常修改密码,通过burpsuite抓包看一下referer字段的参数值是多少

打开一个新的页面构造修改密码的URL:http://127.0.0.1:8080/dvwa/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#

此时修改密码是失败的,通过抓包查看,可以看到没有Referer字段值,将数据包发送repeater重发模块

在数据包重放模块中、在get请求和referer字段同时修改、你现在想修改的密码:比如123456,点击send发送,查看返回值发现修改成功

关键点是:在真实的网络环境中,攻击者并不需要(也不可能)拦截或修改用户的请求

攻击者诱导用户自己去发出“合法的请求”,并利用用户的登录状态(如 Cookie 中的 session)完成敏感操作。

 攻击者构造如下 HTML 页面,诱导用户点击或自动访问,造成好像是一个正常广告弹窗或是页面跳转再或者页面一闪而过的这种现象,让用户以为自己并没有受到攻击:

常见诱导方式

1. 自动提交表单(伪装成广告或页面跳转)

<html><head><meta charset="utf-8"><title>加载中...</title></head><body onload="document.forms[0].submit()"><p>页面加载中,请稍后...</p><form action="http://127.0.0.1:8080/dvwa/vulnerabilities/csrf/" method="GET"><input type="hidden" name="password_new" value="1234" /><input type="hidden" name="password_conf" value="1234" /><input type="hidden" name="Change" value="Change" /></form></body>
</html>

 效果:用户访问页面那一刻就完成了请求,页面一闪而过,就像跳转一样,背后却是密码被修改。

2. 隐藏在图片标签中(GET 请求时)

<img src="http://127.0.0.1:8080/dvwa/vulnerabilities/csrf/?password_new=1234&password_conf=1234&Change=Change" style="display:none;" />

3. 模拟跳转页面 

<script>// 等待1秒再跳转,模拟正常流程setTimeout(function() {window.location.href = 'https://example.com';}, 1000);
</script>

 配合自动提交表单,造成“访问了一个页面 -> 跳转正常页面”,从而掩盖 CSRF 攻击。

攻击者利用的是:

  • 用户处于已登录状态

  • 浏览器会自动携带 Cookie

  • 请求结构与正常请求无差别;

  • 用户以为只是“点错了广告”或“页面加载了一下”。

三、high级别源码分析

<?php// 判断是否点击了“Change”按钮
if( isset( $_POST[ 'Change' ] ) ) {// 检查 Anti-CSRF 令牌是否匹配(防止伪造请求)if ($_POST['user_token'] == $_SESSION['session_token']) {// 获取用户输入的新密码和确认密码$pass_new  = $_POST[ 'password_new' ];$pass_conf = $_POST[ 'password_conf' ];// 判断两个密码是否一致if( $pass_new == $pass_conf ) {// 密码一致,开始处理// 对新密码进行转义,防止SQL注入$pass_new = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new);// 对密码进行MD5加密(注意:实际应用中不推荐使用MD5)$pass_new = md5( $pass_new );// 构造 SQL 更新语句,修改当前登录用户的密码$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";// 执行 SQL 更新操作$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );// 修改成功,反馈给用户echo "<pre>Password Changed.</pre>";} else {// 两次密码输入不一致,提示错误echo "<pre>Passwords did not match.</pre>";}} else {// CSRF token 不匹配,提示错误echo "<pre>CSRF token is incorrect</pre>";}
}?>

当前 High 级别 CSRF 防御机制:

  1. 攻击者构造表单时

    • 表单里的 user_token 是攻击者自己从页面里复制下来的(静态)。

    • 这个 token 属于攻击者自己的 session,和受害者无关。

  2. 受害者点击攻击链接时

    • 表单是提交到了 DVWA,但服务器会拿 GET 请求里的 user_token 去和受害者 session 中真正的 token 做对比。

    • 由于两个 token 不一致(攻击者不能预测受害者的 token),校验失败。

    • 最终返回:“That request didn’t look correct.”


也就是说:

DVWA High 级别的防御逻辑可以总结为:

🔒 验证 token 是否和当前 session 匹配,匹配才能执行敏感操作(如改密码)。

所以只要你作为攻击者 无法控制受害者 session 中的 token 值,你就不能完成攻击 ✅


附加说明(常见误区):

误解真相
我复制了token,能不能直接用?❌ 不行,因为那是你自己的,不是受害者的
用户打开了我的页面,是不是能自动提交?✅ 表单可以提交,但服务器不会放行
我伪造Referer或者User-Agent就能骗过吗?❌ 在 High 级别中,主要靠 token 防御,Referer 检查不是核心


可以试试 如何绕过 token 机制(比如通过 XSS 拿 token),这才是后续更高阶的玩法。由于这个已经不是纯粹的csrf了,所以这里不做其他尝试。

四、impossible级别源码分析

if( isset( $_GET[ 'Change' ] ) ) {  // 判断是否点击了“Change”按钮,即URL中是否有Change参数// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );  // 校验请求中传入的token与session中的token是否一致,防止CSRF攻击// Get input$pass_curr = $_GET[ 'password_current' ];  // 获取当前密码$pass_new  = $_GET[ 'password_new' ];  // 获取新密码$pass_conf = $_GET[ 'password_conf' ];  // 获取确认的新密码// Sanitise current password input$pass_curr = stripslashes( $pass_curr );  // 去除可能的转义字符$pass_curr = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_curr ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));  // 对密码进行SQL注入防护,防止恶意代码注入$pass_curr = md5( $pass_curr );  // 将密码进行md5加密// Check that the current password is correct$data = $db->prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );  // 查询数据库,验证当前密码是否正确$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );  // 获取当前用户$data->bindParam( ':password', $pass_curr, PDO::PARAM_STR );  // 绑定加密后的当前密码$data->execute();  // 执行查询// Do both new passwords match and does the current password match the user?if( ( $pass_new == $pass_conf ) && ( $data->rowCount() == 1 ) ) {  // 检查新密码是否一致,且当前密码是否正确// It does!$pass_new = stripslashes( $pass_new );  // 去除新密码中的转义字符$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));  // 对新密码进行SQL注入防护$pass_new = md5( $pass_new );  // 将新密码进行md5加密// Update database with new password$data = $db->prepare( 'UPDATE users SET password = (:password) WHERE user = (:user);' );  // 更新数据库中的密码$data->bindParam( ':password', $pass_new, PDO::PARAM_STR );  // 绑定新密码$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );  // 绑定当前用户$data->execute();  // 执行密码更新// Feedback for the userecho "<pre>Password Changed.</pre>";  // 密码修改成功的反馈}else {// Issue with passwords matchingecho "<pre>Passwords did not match or current password incorrect.</pre>";  // 密码不匹配或当前密码错误的反馈}
}// Generate Anti-CSRF token
generateSessionToken();  // 生成新的CSRF token并保存在session中,以防下一次攻击

相比于 medium.phpimpossible.php 在防止 CSRF 攻击和增强安全性方面有显著的提升,主要体现在以下几个方面:

1. 引入了 CSRF Token 校验

  • medium.php 中并没有明确验证 CSRF Token。攻击者可以构造恶意请求,只要用户不注意,就可能修改密码。

  • impossible.php 引入了 checkToken() 函数来验证 CSRF Token。每次用户发起请求时,必须携带有效的 user_token(即从用户的 session 中生成并与页面一同呈现的 token)。这样就防止了 CSRF 攻击,因为攻击者无法预测或伪造正确的 CSRF Token

关键代码

checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

该函数会比对请求中的 user_token 与当前 session 中存储的 session_token,如果不匹配,则请求会被拒绝。

2. 使用了预处理语句(Prepared Statements)

  • medium.php 通过直接拼接 SQL 查询来更新数据库,虽然使用了 mysqli_real_escape_string() 防止 SQL 注入,但这种做法依然不够安全,因为它易受复杂注入攻击的影响。

  • impossible.php 使用了 PDO 预处理语句来执行数据库操作,提供了更高的 SQL 注入防护,因为它通过绑定参数的方式来避免 SQL 注入风险。并且这种方法更具可扩展性和维护性。

关键代码

$data = $db->prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
$data->bindParam( ':password', $pass_curr, PDO::PARAM_STR );
$data->execute();

3. 增加了密码确认机制

  • medium.php 仅检查新密码和确认密码是否一致。

  • impossible.php 进一步增加了对 当前密码 的验证,确保用户提供的当前密码是正确的,并且只有在当前密码正确的情况下,才允许更改新密码。

关键代码

$data = $db->prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
$data->bindParam( ':password', $pass_curr, PDO::PARAM_STR );
$data->execute();

4. 错误处理和反馈更加清晰

  • medium.php 直接打印错误信息或反馈内容,但在一些情况下错误信息可能泄露一些内部系统信息。

  • impossible.php 做了适当的错误处理,向用户提供了更清晰的反馈,区分了不同的错误情况,如密码不匹配或当前密码错误,增强了用户体验和系统的安全性。

5. 密文加密

  • medium.php 中,密码使用 MD5 进行加密,但没有明确提到加盐(Salt)等其他加密增强措施。

  • impossible.php 虽然仍然使用了 MD5 加密(不够安全),但其增加了对输入的字符串的 清洗SQL注入防护,这比 medium.php 的做法要安全一些,尤其是在防止恶意注入方面。

6. 会话令牌(Session Token)管理

  • impossible.php 中,成功修改密码后,生成了新的 CSRF Token,并将其存储在 Session 中。这种机制防止了同一会话中多次提交相同的恶意请求,增强了会话的安全性。

关键代码

generateSessionToken();  // 生成新的CSRF token并保存在session中

总结

impossible.php 相比于 medium.php 增强了安全性,尤其在防止 CSRF 攻击SQL 注入 方面。通过引入 CSRF Token 校验,使用 PDO 预处理语句,以及 当前密码验证,使得该页面更加健壮和安全。虽然依然使用了 MD5 加密算法,理论上仍然可以进一步加强密码存储的安全性(如使用更强的哈希算法,比如 bcrypt),但其加强的防护措施已显著降低了攻击的风险。

相关文章:

DVWA靶场保姆级通关教程--03CSRF跨站请求伪造

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 前言 一、low级别的源码分析 二、medium级别源码分析 安全性分析 增加了一层 Referer 验证&#xff1a; 关键点是&#xff1a;在真实的网络环境中&a…...

LangChain:大语言模型应用的“瑞士军刀”入门指南

LanChain入门指南 什么是LangChain&#xff1f;LangChain的核心价值1. 模块化设计 - AI界的"乐高积木"2. 典型应用场景 快速入门实战环境准备&#xff08;5分钟&#xff09;第一个示例&#xff1a;公司命名生成器&#xff08;10分钟&#xff09;进阶功能&#xff1a;…...

Mac电脑,idea突然文件都展示成了文本格式,导致ts,tsx文件都不能正常加载或提示异常,解决方案详细说明如下

有一天使用clean my mac软件清理电脑 突然发现idea出现了文件都以文本格式展示&#xff0c;如图所示 然后就卸载&#xff0c;计划重新安装&#xff0c;安装了好几个版本&#xff0c;并且setting->file types怎么设置都展示不对&#xff0c;考虑是否idea没卸载干净&#xff…...

如何将本地 Jar 包安装到 Maven 仓库(以 Aspose 为例)

在实际开发中&#xff0c;我们经常会遇到一些第三方库&#xff08;如商业库 Aspose&#xff09;无法通过 Maven 仓库直接引入的情况。这时&#xff0c;我们可以手动将 jar 包安装到本地 Maven 仓库&#xff0c;然后像普通依赖一样使用它。 本文以 Aspose.Slides 和 Aspose.Wor…...

[Linux]多线程(一)充分理解线程库

标题&#xff1a;[Linux]多线程 水墨不写bug 文章目录 一、线程的概念1、一句话总结区分进程和线程2、如何理解&#xff1f;3、那么进程和线程的对比&#xff1f;4、Linux为什么要这样设计进程和线程&#xff0c;难道不乱吗&#xff1f;5、从CPU的角度看待执行流&#xff1f;-…...

Mysql order by 用法

ORDER BY 是 SQL 里用于对查询结果进行排序的子句&#xff0c;它能够让查询结果按照指定的列或表达式进行升序或者降序排列&#xff0c;使数据呈现出更有规律的顺序&#xff0c;方便用户查看和分析。下面详细阐述其作用和用法 作用 ORDER BY 的主要作用是对查询结果集进行排序…...

嵌入式学习--江协51单片机day1

今天学习了led灯的相关操作以及独立按键对于led灯的控制。 led灯的相关操作 led灯的相关操作包括点亮&#xff0c;闪烁&#xff0c;流水灯以及流水灯plus 点亮 开发板的led灯是低电平有效&#xff0c;也就是当我们设置0时亮&#xff0c;1时灭。 P2是开发板的led灯模块的8位…...

uniapp开发11-v-for动态渲染list列表数据

uniapp开发11-v-for动态渲染list列表数据&#xff01;下面是一个简单的动态渲染list列表数据的案例。我们现在还未对接真正的后台接口&#xff0c;所以我们直接在页面组件内部&#xff0c;返回一个json数组&#xff0c;模拟从服务器远程获取到的新闻列表信息。来达到渲染输出的…...

qt国际化翻译功能用法

文章目录 [toc]1 概述2 设置待翻译文本3 生成ts翻译源文件4 编辑ts翻译源文件5 生成qm翻译二进制文件6 加载qm翻译文件进行翻译 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt开发经验 &#x1f448; 1 概述 在 Qt 中&#xff0c;ts 文件和 qm 文件是用于国…...

nut-list和nut-swipe搭配:nut-cell侧滑定义无法冒泡打开及bug(含代码、案例、截图)

nut-list和nut-swipe搭配:nut-cell侧滑定义无法冒泡打开及bug(含代码、案例、截图) Nut-UI 官方文档: swipe侧滑手势: https://nutui.jd.com/h5/vue/4x/#/zh-CN/component/swipelist 虚拟列表: https://nutui.jd.com/h5/vue/4x/#/zh-CN/component/list疑问+bug+解决方式:…...

WebRTC并非万能:RTMP与RTSP的工程级价值再认识

不是所有低延迟场景都需要WebRTC&#xff1a;RTMP/RTSP的技术硬实力解析 ——来自大牛直播SDK的实战分析与底层技术对比 一、WebRTC是热潮&#xff0c;但不是银弹 近年来&#xff0c;WebRTC频频出现在技术选型会议上&#xff1a; “浏览器直连&#xff0c;免插件”&#xff1b…...

Factorio 异星工厂 [DLC 解锁] [Steam] [Windows SteamOS]

Factorio 异星工厂 [DLC 解锁] [Steam] [Windows & SteamOS] 注意 这个符号表示 可打开折叠内容 需要有游戏正版基础本体&#xff0c;安装路径不能带有中文&#xff0c;或其它非常规拉丁字符&#xff1b;请务必阅读 使用说明 &#xff08;最新以网站说明为准&#xff09…...

LLM的min_p 参数详

min_p 参数详解 min-p采样,源自论文"Min P Sampling: Balancing Creativity and Coherence at High Temperature"。在大语言模型(LLM)中,min_p 通常是指在生成文本时的最小概率阈值(Minimum Probability),用于控制输出 token 的选择,特别是在核采样(Nucleus…...

C语言_可变参数_LOG宏

LOG宏一般处理&#xff0c;没有参数&#xff0c;只有字符串参数&#xff0c;字符串格式和一个参数&#xff0c;多个参数的场合。以下是针对常见的应用场合举例说明&#xff0c;可便参数的使用。 代码 #include <stdio.h>#define LOG(format, ...) printf("[%s][%…...

19.第二阶段x64游戏实战-vector容器

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;18.第二阶段x64游戏实战-MFC列表框 vector是一个封装了动态大小数组的顺序容器…...

第九节:图像处理基础-图像几何变换 (缩放、旋转、平移、翻转)

引言 在计算机视觉和图像处理领域&#xff0c;几何变换是最基础且应用最广泛的技术之一。通过改变图像的几何结构&#xff0c;我们可以实现图像缩放以适应不同分辨率设备&#xff0c;旋转图像以校正方向偏差&#xff0c;平移目标物体进行位置对齐&#xff0c;或通过翻转操作增…...

jmeter 执行顺序和组件作用域

本章节主要讲解“JMeter执行顺序与作用域”的内容&#xff0c;类似于运算符或操作符的优先级&#xff0c;当JMeter测试中包含多个不同的元素时&#xff0c;哪些元素先执行&#xff0c;哪些元素后执行&#xff0c;并不是严格按照它们出现的先后顺序依次有序执行的&#xff0c;而…...

mvc-review

review: 1.最初的做法&#xff1a;一个请求对应一个servlet&#xff0c;这样存在的问题是servlet太多了 2.改动&#xff1a;把一系列请求都对应一个servlet&#xff0c; IndexServlet / AddServlet / DelServlet / UpdateServlet ...-> 合并成FruitServlet 通过一个oper…...

基于ResNet50的手写符号识别系统

基于ResNet50的手写符号识别系统 项目概述 本项目实现了两个手写符号识别模型&#xff1a; ABCD字母识别模型&#xff1a;用于识别手写的A、B、C、D四个字母✓符号识别模型&#xff1a;用于识别手写的对勾(✓)和叉号() 两个模型均基于ResNet50预训练模型&#xff0c;采用迁…...

SpringBoot教学管理平台源码设计开发

概述 基于SpringBoot框架开发的​​教学管理平台​​完整项目&#xff0c;帮助开发者快速搭建在线教育平台。该系统包含学生端、教师端和管理后台&#xff0c;实现了课程管理、随堂测试、作业提交等核心功能&#xff0c;是学习SpringBoot开发的优质案例。 主要内容 1. 系统架…...

C++负载均衡远程调用学习之集成测试与自动启动脚本

目录 01 Lars-LbAgentV0.7-route_lb获取路由全部主机信息 02 Lars-LbAgentV0.7-API模块注册功能实现和测试工 03 Lars-LbAgentV0.7-项目构建工具 04 Lars-LbAgentV0.7-启动工具脚本实现 05 Lars-有关fd泄露的调试办法 06 Lars-qps性能测试 07 git企业开发基本流程 01 Lar…...

双ISP(双互联网服务提供商)

目录 核心作用 适用场景 实现方式 优缺点 假设一家外贸公司 双ISP&#xff08;双互联网服务提供商&#xff09; 是指用户同时接入两个不同的网络服务提供商&#xff08;Internet Service Provider&#xff09;&#xff0c;通过冗余设计或负载均衡技术&#xff0c;提升网络…...

网工实验——静态路由与BFD联动

网络拓扑图 实验目的&#xff1a; PC与Server通信的时候主要走上面&#xff0c;当主用电路失效的时候走下面 设备&#xff1a; 一台PC主机 一台Server服务器 两台Router路由器 一台S3700交换机 配置 1.配置PC和Server的IP地址 PC Server 2.配置路由器 R3配置对应接口…...

谷歌在即将举行的I/O大会之前,意外泄露了其全新设计语言“Material 3 Expressive”的细节

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

【网络原理】IP协议

目录 ​编辑 一. IP协议的作用 二. IP协议报头 三. 拆包和组包 四. 地址管理 1&#xff09;动态分配IP地址 2&#xff09;NAT机制&#xff08;网络地址映射&#xff09; 3&#xff09; IPV6 五. IP转换 1&#xff09;客户端到服务器 2&#xff09;服务器到客户端 六…...

【Python 文件I/O】

Python 的文件 I/O 操作是数据处理的基础技能&#xff0c;涉及文件的读写、路径管理、异常处理等核心功能。以下是文件 I/O 的核心知识点&#xff1a; 一、基础文件操作 1. 打开文件 # 通用模式&#xff1a;r(读)/w(写)/a(追加) b(二进制)/t(文本&#xff0c;默认) f open(…...

torchrun单机多卡运行

torchrun命令使用 torchrun示例 export CUDA_VISIBLE_DEVICES0,1,2 nohup torchrun \--nproc_per_node3 \--nnodes1 \--node_rank0 \--master_addr"127.0.0.1" \--master_port1225 \/data/train.py \--batch_size 32 \--size 320运行如上sh命令发现&#xff0c;即 …...

数据管理平台是什么?企业应如何做好数据化管理?

目录 一、数据管理是什么&#xff1f; 二、数据管理平台有哪些作用&#xff1f; 1. 数据采集与整合 2. 数据清洗与预处理 3. 数据分析与挖掘 4. 数据共享与协作 三、企业应如何做好数据化管理&#xff1f; 1. 建立数据管理战略 2. 完善数据管理制度 3. 培养数据管理人…...

GuassDB如何创建兼容MySQL语法的数据库

GaussDB简介 GaussDB是由华为推出的一款全面支持OLTP和OLAP的分布式关系型数据库管理系统。它采用了分布式架构和高可靠性设计&#xff0c;可以满足大规模数据存储和处理的需求。GaussDB具有高性能、高可靠性和可扩展性等特点&#xff0c;适用于各种复杂的业务场景&#xff0c…...

Qt国际化实战--精通Qt Linguist工具链

概述 在全球化的今天,软件产品需要支持多种语言和地区,以满足来自世界各地用户的需求。Qt框架提供了一套完整的工具集来帮助开发者实现应用程序的国际化(i18n)和本地化(l10n),其中最核心的就是Qt Linguist工具链 关于国际化与本地化 国际化(i18n): 指的是设计和开发…...

C++内联函数

总结&#xff1a;内联函数是把函数变成一个代码块直接塞入源程序中&#xff0c;省去了一些参数传递和栈操作&#xff08;省时间&#xff09;&#xff0c;但是同时又增加了代码的大小&#xff08;因为原本的函数只有会使用指针指向该函数&#xff0c;但是内联函数是直接塞入&…...

26届秋招收割offer指南

26届暑期实习已经陆续启动&#xff0c;这也意味着对于26届的同学们来说&#xff0c;“找工作”已经提上了日程。为了帮助大家更好地准备暑期实习和秋招&#xff0c;本期主要从时间线、学习路线、核心知识点及投递几方面给大家介绍&#xff0c;希望能为大家提供一些实用的建议和…...

Python之内省与反射应用

Python之内省与反射应用 Python作为一门动态语言&#xff0c;具备了强大的内省&#xff08;Introspection&#xff09;与反射&#xff08;Reflection&#xff09;机制。这两个概念在运行时查看对象的属性、类型、方法等信息&#xff0c;甚至可以动态调用方法或修改对象的属性。…...

第三章:langchain加载word文档构建RAG检索教程(基于FAISS库为例)

文章目录 前言一、载入文档&#xff08;word&#xff09;1、文档载入代码2、文档载入数据解读&#xff08;Docx2txtLoader方法&#xff09;输入数据输出文本内容 3、Docx2txtLoader底层代码文档读取解读Docx2txtLoader底层源码示例文档读取输出结果 二、文本分割1、文本分割代码…...

球速最快的是哪种球类运动·棒球1号位

在体育运动中&#xff0c;球速最快的项目与棒球结合来看&#xff0c;可以分两个角度解读&#xff1a; 一、球速最快的运动项目 羽毛球以426公里/小时&#xff08;吉尼斯纪录&#xff09;的杀球速度位列榜首&#xff0c;远超棒球投球速度。其极速源于&#xff1a; 羽毛球拍甜区…...

TVM中Python如何和C++联调?

1. 编译 Debug 版本 # 在项目根目录下创建构建目录&#xff08;若尚未创建&#xff09; mkdir -p build && cd build# 配置 Debug 构建 cmake -DCMAKE_BUILD_TYPEDebug ..# 编译&#xff08;根据 CPU 核心数调整 -j 参数&#xff09; make -j$(nproc)2. 获取 Python 进…...

从零实现基于Transformer的英译汉任务

1. model.py&#xff08;用的是上一篇文章的代码&#xff1a;从0搭建Transformer-CSDN博客&#xff09; import torch import torch.nn as nn import mathclass PositionalEncoding(nn.Module):def __init__ (self, d_model, dropout, max_len5000):super(PositionalEncoding,…...

在 PyTorch 中借助 GloVe 词嵌入完成情感分析

一. Glove 词嵌入原理 GloVe是一种学习词嵌入的方法&#xff0c;它希望拟合给定上下文单词i时单词j出现的次数。使用的误差函数为&#xff1a; 其中N是词汇表大小&#xff0c;是线性层参数&#xff0c; 是词嵌入。f(x)是权重项&#xff0c;用于平衡不同频率的单词对误差的影响…...

大数据应用开发和项目实战-电商双11美妆数据分析

数据初步了解 &#xff08;head出现&#xff0c;意味着只出现前5行&#xff0c;如果只出现后面几行就是tail&#xff09; info shape describe 数据清洗 重复值处理 这个重复值是否去掉要看实际情况&#xff0c;比如说&#xff1a;昨天卖了5瓶七喜&#xff0c;今天卖了5瓶七…...

web服务

一、nginx的安装与启用 nginx的安装 开源版本的Nginx官网&#xff1a;http://nginx.org Nginx在安装的过程中可以选择源码安装也可以选择使用软件包安装 源码安装下载相应的源码压缩包解压后编译完成安装 软件安装包可以使用rpm或者apt命令进行安装&#xff0c;也可以使用dnf…...

在Spring Boot 中如何配置MongoDB的副本集 (Replica Set) 或分片集群 (Sharded Cluster)?

在 Spring Boot 中配置 MongoDB 副本集 (Replica Set) 或分片集群 (Sharded Cluster) 非常相似&#xff0c;主要区别在于连接字符串 (URI) 中提供的主机列表和一些特定选项。 最常的方式是使用 spring.data.mongodb.uri 属性配置连接字符串。 1. 连接到 MongoDB 副本集 (Repl…...

Oracle中游标和集合的定义查询及取值

在 Oracle 存储过程中&#xff0c;使用游标处理自定义数据行类型时&#xff0c;可以通过 定义记录类型&#xff08;RECORD&#xff09; 和 游标&#xff08;CURSOR&#xff09; 结合实现。 1. 定义自定义记录类型 使用 TYPE … IS RECORD 定义自定义行数据类型&#xff1a; DE…...

Python企业级MySQL数据库开发实战指南

简介 Python与MySQL的完美结合是现代Web应用和数据分析系统的基石,能够创建高效稳定的企业级数据库解决方案。本文将从零开始,全面介绍如何使用Python连接MySQL数据库,设计健壮的表结构,实现CRUD操作,并掌握连接池管理、事务处理、批量操作和防止SQL注入等企业级开发核心…...

【LLM】Open WebUI 使用指南:详细图文教程

Open WebUI 是一个开源的、可扩展且用户友好的自托管 AI 平台,专为生成式人工智能模型交互而设计。 Open WebUI 旨在为用户提供一个简单易用、功能强大且高度定制化的界面,使其能够轻松与各种 AI 模型(如文本生成、图像生成、语音识别等)进行交互。 一、安装与初始化配置 扩…...

前端封装框架依赖管理全攻略:构建轻量可维护的私有框架

前端封装框架依赖管理全攻略&#xff1a;构建轻量可维护的私有框架 前言 在自研前端框架的开发中&#xff0c;依赖管理是决定框架可用性的关键因素。不合理的依赖设计会导致&#xff1a; 项目体积膨胀&#xff1a;重复依赖使最终打包体积增加30%版本地狱&#xff1a;不同项目…...

Listremove数据时报错:Caused by: java.lang.UnsupportedOperationException

看了二哥的foreach陷阱后&#xff0c;自己也遇见了需要循环删除元素的情况&#xff0c;立马想到了当时自己阴差阳错的避开所有坑的解决方式&#xff1a;先倒序遍历&#xff0c;再删除。之前好使&#xff0c;但是这次不好使了&#xff0c;报错Caused by: java.lang.UnsupportedO…...

互联网大厂Java求职面试:云原生与AI融合下的系统设计挑战-1

互联网大厂Java求职面试&#xff1a;云原生与AI融合下的系统设计挑战-1 在当今云计算和人工智能迅猛发展的背景下&#xff0c;互联网大厂对Java工程师的要求已从传统的单体架构和业务逻辑处理&#xff0c;转向了更复杂的云原生架构设计、AI模型集成以及高并发系统的性能优化能…...

并发设计模式实战系列(16):屏障(Barrier)

&#x1f31f; 大家好&#xff0c;我是摘星&#xff01; &#x1f31f; 今天为大家带来的是并发设计模式实战系列&#xff0c;第十六章屏障&#xff08;Barrier&#xff09;&#xff0c;废话不多说直接开始~ 目录 一、核心原理深度拆解 1. 屏障的同步机制 2. 关键参数 二…...

pywinauto通过图片定位怎么更加精准的识别图片?

pywinauto通过图片定位怎么更加精准的识别图片&#xff1f; 可以使用置信度的配置&#xff0c;添加了对比图片相似程度达到多少就可以认为是合适的定位图片 import time from time import sleep from pywinauto.application import Application from pywinauto.keyboard impo…...

Spring Cloud Stream集成RocketMQ(kafka/rabbitMQ通用)

什么是Spring Cloud Stream Spring Cloud Stream 是 Spring 生态系统中的一个框架&#xff0c;用于简化构建消息驱动微服务的开发和集成。它通过抽象化的方式将消息中间件&#xff08;如 RabbitMQ、Kafka、RocketMQ 等&#xff09;的复杂通信逻辑封装成简单的编程模型&#xf…...