序列化和反序列化(一)
因为通过这段时间的学习,发现,序列化和反序列化的考点和漏洞在平时遇到的还是比较多的,而且自己也没有特别去学习过这个知识点,所以在这里写一篇关于这里序列化和反序列话的博客,废话就停止在这里了。
在介绍具体的序列化和反序列化基础之前,因为没有系统性地整理过php的知识点,所以还是选择整理一下php的一些基础知识点
php面向对象基本概念、类与对象
一.面向对象
(一)基本介绍
面向对象(Object-Oriented,简称 OO)是一种编程思想和方法,它将程序中的数据和操作数据的方法封装在一起,形成"对象",并通过对象之间的交互和消息传递来完成程序的功能。
在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。举个例子,在现实世界里我们所面对的事情都是对象,如计算机、电视机、自行车等。
PHP 面向对象 | 菜鸟教程
面向对象编程强调数据的封装、继承、多态和动态绑定等特性,使得程序具有更好的可扩展性、可维护性和可重用性。
(二)面向对象编程三大特征:封装、继承、多态
1、封装:将对象的属性和行为封装起来,将对象的属性和行为封装起来的载体就是类
2、继承:继承性是子类自动共享父类数据结构和方法的机制,是类之间的一种关系;当处理一个问题时,可以将一些有用的类保留下来,这些类通常有相同的属性甚至相同的方法,当遇到同样的问题时可以拿来复用。
父类:一个类被其它类继承,可将该类成为父类;
子类:一个类继承其他类称为子类(派生类);
3、多态:将父类对象应用于子类的特征就是多态。子类继承了父类的特点,同时子类又有自己的特点即是多态,多态指的是一个类的实例(对象)可以表现出多种形态。
二.面向过程
面向过程是一种以“整体事件”为中心的编程思想,编程的时候把解决问题的步骤分析处理,然后用函数把这些步骤实现,再一步步的具体步骤中再按顺序调用函数。
三.类
(一)定义(类和对象的关系)
类定义了一件事的特点,将数据的形式以及这些数据上的操作封装在一起;对象是具有类类型的变量,是对类的实例;类是想法,把类实例化,调用具体值后就变成对象。
举个例子
class Zerotwo
{//类体:由成员函数(方法)和成员变量(属性)组成//成员变量声明//成员函数声明}
在这个例子里面:
class为定义类的关键字,Zerotwo为类的名字,{}中为类的主体
类体中的内容为类的成员;
类中的变量称为成员变量(属性):定义再类内部的变量,该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可成为对象的属性;
类中的函数称为成员函数(方法):定义在类的内部,可用于访问对象的数据。
(二)类的内容
1.预定义
class Zerotwo
{var $name; //声明成员变量,var是一种修饰符var $sexl; function state($var1) //声明成员函数(方法){echo $this->name; //使用预定义$this调用成员变量echo $var1; //成员函数传参$var1可直接调用}
}
运行结果可见,实际上这个定义了以后,因为只是定义好了类和类体,语言类型等等关键信息都没有加上,所以会被编译器自动识别,然后直接输出。那么接下来我们就要将这个类实例化和赋值
2、实例化和赋值
<?php
class Zerotwo
{var $Darling; //声明成员变量,var是一种修饰符var $Franxx;function state($var1) //声明成员函数(方法){echo $this->Darling; //使用预定义$this调用成员变量echo $var1; //成员函数传参$var1可直接调用}
}
$zzc = new Zerotwo(); //实例化类Zerotwo()为对象zzc
$zzc->Darling = '02,02,02'; //参数赋值
$zzc->Franxx = 'guojiadui';
print_r($zzc); //打印对象?>
那么这里的运行结果就不一样很多了,从运行结果可以看见这里的类Zerotwo被实例化了,并且被对象zzc赋值了
再演示一个不指向的
<?php
class Zerotwo
{var $Darling; //声明成员变量,var是一种修饰符var $Franxx;function state($var1) //声明成员函数(方法){echo $this->Darling; //使用预定义$this调用成员变量echo '关于'.$var1; //成员函数传参$var1可直接调用}
}
$zzc = new Zerotwo(); //实例化类Zerotwo()为对象lin
$zzc->Darling = '02'; //参数赋值
$zzc->state('国家队');//调用函数?>
运行结果
3、类的访问权限修饰符
PHP 支持三种访问修饰符:public
,protected
以及 private
,这些修饰符所提供的访问级别具体如下。
public:公共的,在类的内部、子类中 或者类的外部都可以使用,不受限制;
protected:受保护的,在类的内部、子类中可以使用,但不能在类的外部使用;
private:私有的,只能在类的内部使用,在类的外部或者子类中无法使用。
上图:
还是用刚刚的代码的例子
外部
<?php
class Zerotwo
{public $Franxx = '国家队'; //声明成员变量,var是一种修饰符private $Darling = '02';protected $zerotwo = '比翼鸟';function state($var1) //声明成员函数(方法){echo $this->Darling; //使用预定义$this调用成员变量echo $var1; //成员函数传参$var1可直接调用}
}
$zzc = new Zerotwo(); //实例化类Zerotwo()为对象zzc
echo $zzc->Franxx; //外部可用
echo $zzc->Darling; //外部不可用
echo $zzc->zerotwo; //外部不可用?>
运行结果如下
这里的代码是会报错的,因为违背了封装原则,这里尝试通过 $zzc->Darling 和 $zzc->zerotwo 在类的外部访问私有和受保护属性,就会导致错误,但是这个错误在这里无伤大雅,会在子类那边出错。
子类
再次修改代码进行访问
<?php
class Zerotwo //父类
{public $Franxx = '国家队'; //声明成员变量,var是一种修饰符private $Darling = '02';protected $zerotwo = '比翼鸟';function state($var1) //声明成员函数(方法){echo $this->Darling; //使用预定义$this调用成员变量echo $var1; //成员函数传参$var1可直接调用}
}
class Zerotwo2 extends Zerotwo //子类
{function test(){echo $this->Darling."<br />"; //private子类不可用echo $this->zerotwo."<br />"; //protected子类可用echo $this->Franxx."<br/>"; //public子类可以用}
}
$zzc = new Zerotwo(); //实例化类Zerotwo()为对象zzc
$zzc2 = new Zerotwo2();
echo $zzc->Franxx."<br />"; //外部可用
echo $zzc->Darling; //外部不可用
echo $zzc2->test();?>分析
(这里的"<br />"是html语言的换行,php编译器是无法识别的,只会将它作为字符串输出,php语言的换行可见下面的代码)
这个时候会发现,出错了 ,这个结果并没有像编译的代码一样输出“$zzc2->test();”的内容,这里的原因是因为在 PHP 中,访问私有属性时,如果尝试从类的外部或从子类访问一个私有属性,会导致一个致命错误(Fatal Error)。这种错误会立即停止脚本的执行,因此任何后续的代码,包括 $zzc2->test();
,都不会被执行。这里也是为了演示一下,如果强行去访问私有属性会带来的后果。
修改以后的代码
<?php
class Zerotwo //父类
{public $Franxx = '国家队'; // 公有成员变量private $Darling = '02'; // 私有成员变量protected $zerotwo = '比翼鸟'; // 受保护成员变量function state($var1) // 声明成员函数{echo $this->Darling; // 使用 $this 调用成员变量echo $var1; // 成员函数传参 $var1 可直接调用}
}class Zerotwo2 extends Zerotwo //子类
{function test(){// echo $this->Darling."<br />"; // 不能访问私有属性,需移除或通过方法访问echo $this->zerotwo . PHP_EOL; // 受保护成员变量,子类可用echo $this->Franxx . PHP_EOL; // 公有成员变量,子类可用}
}$zzc = new Zerotwo(); // 实例化类 Zerotwo() 为对象 $zzc
$zzc2 = new Zerotwo2();echo $zzc->Franxx . PHP_EOL; // 外部可用
// echo $zzc->Darling; // 外部不可用,需移除或通过方法访问
$zzc2->test();
?>
(这里的PHP_EOL就是php语言中的换行)
这里下面的两个输出就是由对象zzc2控制的。
那问题又来了,要怎么去访问私有属性呢?还是在原代码的基础上进行修改。
<?php
class Zerotwo //父类
{public $Franxx = '国家队';private $Darling = '02'; //定义了私有成员protected $zerotwo = '比翼鸟';function state($var1) // 声明成员函数{echo $this->Darling; // 使用 $this 调用成员变量echo $var1; // 成员函数传参 $var1 可直接调用}private function test2() //定义私有成员的方法{echo $this->Darling; //在类的内部访问私有成员变量}function test3() //在类的内部访问私有成员的方法{$this->test2();}
}class Zerotwo2 extends Zerotwo //子类
{function test(){// echo $this->Darling; // 私有属性,子类不可用echo $this->zerotwo . PHP_EOL; // 受保护成员变量,子类可用echo $this->Franxx . PHP_EOL; // 公有成员变量,子类可用}
}$zzc = new Zerotwo(); // 实例化类 Zerotwo() 为对象 $zzc
$zzc2 = new Zerotwo2();echo $zzc->Franxx . PHP_EOL; // 外部可用
//echo $zzc->Darling; // 外部不可用,需移除或通过方法访问$zzc2->test();$zzc ->test3(); //通过在类的外部访问Zerotwo中的公有成员,间接访问Zerotwo中的私有成员//私有成员变量无法直接从定义它的类的外部及该类的子类中直接访问
?>
通过这种间接访问的方法,就可以访问到这个私有成员了
这里就不再过多进行实验了,给出关于这个访问修饰符的文章
闪耀的钥匙:PHP 与访问修饰符_php访问修饰符-CSDN博客
序列化基础知识
一.PHP序列化:serialize()
序列化:是将变量或对象转换成字符串的过程( 序列化只作用于对象,不序列化方法),用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构。
简单而言
序列化:将对象的状态信息(属性)转换为可以存储或传输的形式的过程
对象/数组字符串
在php中使用函数serialize()将对象或者数组进行序列化,并返回一个包含字节流的字符串来表示。
php序列化的字母标识:
a - 数组 (Array): 一种数据结构,可以存储多个相同类型的元素。
b - 布尔型 (Boolean): 一种数据类型,只有两个可能的值:true 或 false。
d - 双精度浮点数 (Double): 一种数据类型,用于存储双精度浮点数值。
i - 整型 (Integer): 一种数据类型,用于存储整数值。
o - 普通对象 (Common Object): 一个通用的对象类型,它可以是任何类的实例。
r - 引用 (Reference): 指向对象的引用,而不是对象本身。
s - 字符串 (String): 一种数据类型,用于存储文本数据。
C - 自定义对象 (Custom Object): 指由开发者定义的特定类的实例。
O - 类 (Class): 在面向对象编程中,类是一种蓝图或模板,用于创建对象。
N - 空 (Null): 在许多编程语言中,null 表示一个不指向任何对象的特殊值。
R - 指针引用 (Pointer Reference): 一个指针变量,其值为另一个变量的地址。
U - 统一码字符串 (Unicode String): 一种数据类型,用于存储包含各种字符编码的文本数据。
各类型值的serialize序列化:
空字符 null -> N;
整型 123 -> i:123;
浮点型 1.5 -> d:1.5;
boolean型 true -> b:1;
boolean型 fal -> b:0;
字符串 “haha” -> s:4:"haha";
测试一下看看
(一)对象序列化
<?phpclass Zerotwo //定义了一个test类{public $Franxx = 11;private $Darling = aa;protected $Zerotwo = true;public function zerotwo(){echo $this->Franxx;}}$zzc = new Zerotwo(); //将test这个类实例化echo serialize($zzc); //序列化对象zzc
在这里的输出结果中:(11是公有成员输出的值)
O
: 这是一个标识符,表示接下来的数据是一个对象(O
)-
7:"Zerotwo"
: 这表示对象的类名是Zerotwo
,并且类名包含 7 个字符(实际上应该是 8 个字符,包括引号内的内容)。 -
:3:
: 这表示对象有 3 个属性。 -
{...}
: 花括号内包含了对象的属性和它们的值。-
s:6:"Franxx";i:11;
:s:6:"Franxx"
: 表示一个字符串属性名Franxx
,该字符串有 6 个字符。i:11
: 表示属性值是一个整数11
。
-
s:16:" Zerotwo Darling";s:2:"aa";
:s:16:" Zerotwo Darling"
: 表示一个字符串属性名Zerotwo Darling
,该字符串有 16 个字符(注意前面的空格)。s:2:"aa"
: 表示属性值是一个字符串aa
,该字符串有 2 个字符。
-
s:10:" * Zerotwo";b:1;
:s:10:" * Zerotwo"
: 表示一个字符串属性名* Zerotwo
,该字符串有 10 个字符(注意前面的空格和星号)。b:1
: 表示属性值是一个布尔值true
(在序列化中,布尔值true
被表示为1
,false
被表示为0
)。
-
同时,需要注意的是,protected 和private输出时有不可打印字符,如下图
所以在构造payload的时候,会使用urlencode函数,来实现构造
这里还有补充的一个小点是序列化的格式
序列化格式
- 私有属性(private): 私有属性在序列化时,属性名会被格式化为
"\0类名\0属性名"
,以确保在反序列化时仍然能识别出这是一个私有属性,并且属于哪个类。 - 受保护属性(protected): 受保护属性在序列化时,属性名会被格式化为
"\0*\0属性名"
,其中*
表示受保护属性。 - 公有属性(public): 公有属性在序列化时,属性名不会有特殊前缀,直接使用属性名。
这种序列化格式确保了在序列化和反序列化过程中,属性的可见性和所属类信息不会丢失。
(二)成员属性调用对象
<?php
class Zerotwo
{var $zzc='zhu';function test(){echo $this->zzc;}
}class Zerotwo2
{var $abc;function __construct() //使用了__construct魔术方法构造函数{$this->abc=new Zerotwo();}}$a = new Zerotwo2();
echo serialize($a);
在这个例子中,实例化的对象$a的成员变量‘abc’调用实例化后的对象Zerotwo()
(三)pop链序列化
面向属性编程POP( Property Oriented Programming)
POP链就是利用魔法方法在里面进行多次跳转然后获取敏感数据的一种payload
<?php
class Zerotwo
{public $a="11";public $b=true;public $c=0202;
}
class Zerotwo2
{public $d;public $e="zzczzc";
}$m=new Zerotwo();
$n=new Zerotwo2();
$n->f=$m;
echo serialize($n);
代码中,$n->f = $m;
这一行是将$m
对象赋值给$n
对象的新属性$f
。这里,$f
是动态创建的,并不是在Zerotwo2
类的定义中显式声明的。这里m的值被嵌套在了n里面
(四)数组序列化
<?php
$zzc=array("zerotwo",0202,false);
echo serialize($zzc);
这里的
a表示这是一个数组的序列化(上面的内容有提到),成员属性名为数组的下标,格式 {i:数组下标;类型:长度:“值”; 以此类推}
二.PHP反序列化(unserialize)
(一)反序列化的特性
1.反序列化之后的内容为一个对象;
2.反序列化生成的对象里的值,由反序列化里的值提供;与原有类预定义的值无关;
3.反序列化不触发类的成员方法;需要调用方法后才能触发
(二)反序列化的作用
反序列化:将序列化后的参数还原成实例化的对象。
字符串对象
(三)例子演示
<?php
class Zerotwo
{public $Franxx = 'zzc';private $Darling = 0202;protected $zerotwo = true;public function displayVar(){echo $this->Franxx;}
}
$d=new Zerotwo();
$b=serialize($d);
print_r(unserialize($b));$a='O:7:"Zerotwo":3:{s:6:"Franxx";i:123123123;s:16:" Zerotwo Darling";s:2:"aa";s:10:" * Zerotwo";b:1;}';//反序列化生成的对象的成员属性值由被反序列化的字符串决定,与原来类预定义的值无关
$c=unserialize($a); //$c把字符串$b反序列化为对象
var_dump($c); //var_dump()用于打印变量的相关信息,包括变量的类型,值,长度等
在这个例子中,可以发现的是,反序列化生成的对象里的值,由反序列化里的值提供;与原有类预定义的值无关。为了方便观察,我将一开始预定义里面的值也打印出来了。
<?php
class Zerotwo
{public $Franxx = 'zzc';protected $Darling = 0202;private $zerotwo = true;public function displayVar(){echo $this->Franxx; //这里没有被调用}
}
$d = 'O:7:"Zerotwo":3:{s:6:"Franxx";i:123123123;s:16:" Zerotwo Darling";s:2:"aa";s:10:" * Zerotwo";b:1;}';
$a = urldecode($d);
$c = unserialize($a);
$c->displayVar();
在这个例子中,反序列化不触发类的成员方法;需要调用方法后才能触发。
$d = 'O:7:"Zerotwo":3:{s:6:"Franxx";i:123123123;s:16:" Zerotwo Darling";s:2:"aa";s:10:" * Zerotwo";b:1;}';
$a = urldecode($d);
$c = unserialize($a);
这段代码将字符串反序列化为一个 Zerotwo
类的对象 $c
。但是,反序列化过程并不会调用 Zerotwo
类中的任何方法。只有当显式调用 $c->displayVar()
方法时,displayVar
方法中的代码才会被执行。
$c->displayVar();
在这个方法中,echo $this->Franxx;
会输出 Franxx
属性的值。在反序列化后的对象中,Franxx
的值被设置为 123123123
,因此调用 displayVar
方法将输出 123123123
。
(四)反序列化漏洞(简单介绍扩展一下)
1.PHP反序列化漏洞成因
通过上面的代码,可知在反序列化过程中,unserialize()接收的值(字符串)可控;通过改变这个值(字符串),得到所需要的代码,即生成的对象的属性值。
通过调用方法,触发代码执行。简单来讲,大概就是一种允许攻击者通过将恶意数据反序列化为PHP对象来执行任意代码的漏洞,我现在的理解是这样的。
2. PHP反序列化工作原理
PHP反序列化是一种将存储在字符串中的PHP对象转换为PHP变量的过程。这可以通过使用unserialize()函数来实现。
unserialize()函数:将字符串中的数据解析为一个PHP对象,并将其分配给一个变量。
3.PHP 反序列化漏洞的常见方法
(1)反弹 Shell。 这是一种在远程计算机上执行命令的方法。可以通过使用 exec() 或 system() 等函数来完成。
(2)文件上传。 这是一种将文件上传到远程计算机的方法。可以通过使用 move_uploaded_file() 函数来完成。
(3)本地文件包含。 这是一个在远程计算机上包含本地文件的方法。可以通过使用 include() 或 require() 等函数来完成。
(4)数据库访问。 这是一个访问远程计算机上的数据库的方法。可以通过使用 mysql_connect() 或 mysqli_connect() 等函数来完成。
4.防御PHP反序列化漏洞
(1)使用最新版本的 PHP。 最新版本的 PHP 通常包含针对已知漏洞的修复程序。
(2)禁用反序列化。 可以通过在 php.ini 文件中设置 unserialize_callback_func 选项来禁用反序列化。
(3)验证用户输入。 在对用户输入进行反序列化之前,请务必对其进行验证。
(4)使用白名单。 仅允许反序列化来自受信任来源的字符串。
(5)使用签名。 在序列化字符串之前,请使用签名对其进行签名。这将有助于防止恶意字符串被反序列化。
(五)魔术方法
魔术方法是一个预定好的、在特定情况下自动触发的行为方法。(触发前提:魔术方法所在的类被调用)
__construct 当一个对象创建时被调用,__destruct 当一个对象销毁时被调用,__toString 当一个对象被当作一个字符串被调用。__wakeup() 使用unserialize时触发__sleep() 使用serialize时触发__destruct() 对象被销毁时触发__call() 对不存在的方法或者不可访问的方法进行调用就自动调用__callStatic() 在静态上下文中调用不可访问的方法时触发__get() 用于从不可访问的属性读取数据__set() 在给不可访问的(protected或者private)或者不存在的属性赋值的时候,会被调用__isset() 在不可访问的属性上调用isset()或empty()触发__unset() 在不可访问的属性上使用unset()时触发__toString() 把类当作字符串使用时触发,返回值需要为字符串__invoke() 当脚本尝试将对象调用为函数时触发__clone() 使用clone关键字拷贝完一个对象后触发
......
还是来一波实操
1.对象被创建时触发__construct()方法,对象使用完被销毁时触发__destruct()方法
<?php
class Zerotwo
{public $Darling = "02";public function __construct(){echo "创建成功----";}public function __destruct(){echo "销毁成功";}
}$Darling = new Zerotwo();
实例化test类为对象赋值给a时就被触发。
2.对象被序列化时触发__sleep(),字符串被反序列化时触发__wakeup()
<?php
class Zerotwo
{public $Darling = "02";public function __sleep(){echo "使用了serialize()----";return array("Darling");}public function __wakeup(){echo "使用unserialize";}
}$Darling = new Zerotwo();
$Franxx=serialize($Darling);
$zerotwo=unserialize($Franxx);
3.echo $a 把对象当成字符串输出触发__toString(),$a() 把对象当成函数执行触发__invoke()
<?php
class Zerotwo
{public $Darling = "02";public function __toString(){return "字符串----";}public function __invoke(){echo "函数";}
}$Darling = new Zerotwo();
echo $Darling;
$Darling ();
4.$a->callxxx() 调用了不存在的方法 触发__call()方法
<?php
class Zerotwo
{public function __call($Franxx,$Darling){echo "鸡鸣寺的樱花开了";}
}
$Franxx = new Zerotwo();
$Franxx->callxxx();
$a::callxxx() 静态调用 或 调用成员常量时使用不存在的方法,触发 __callStatic()方法
<?php
class Zerotwo
{public function __callStatic($Franxx,$Darling){echo "$Franxx";}
}
$Franxx = new Zerotwo();
$Franxx::callxxx();
5.调用成员属性不存在时触发__get()方法
<?php
class Zerotwo
{public $Darling;public function __get($Darling){echo $Darling;}
}$zerotwo= new Zerotwo();
$zerotwo->Franxx;
6.给不存在的成员属性赋值时触发__set()方法
<?php
class Zerotwo
{public $Darling;public function __set($Darling,$Franxx){echo "$Franxx,$Darling";}
}$zerotwo= new Zerotwo();
$zerotwo->zzc=0202;
传参$Franxx,$Darling,返回不存在的成员属性名称及其值
这里特意换了一下位置看看
7.对不可调用的属性使用isset()或empty()时,isset()会被调用
对不可调用的属性使用unset()时,unset()会被调用
传参$Darling,返回不存在的成员属性名称
<?php
class Zerotwo
{protected $Darling;public function __isset($Darling){echo "$Darling";}
}$zerotwo= new Zerotwo();
isset($zerotwo->Darling);
<?php
class Zerotwo
{protected $Darling;public function __unset($Darling){echo "$Darling";}
}$zerotwo= new Zerotwo();
unset($zerotwo->DarlingDarling);
8.使用clone拷贝完成一个对象后,新对象会自动调用__clone()方法
<?php
class Zerotwo
{public $Darling='0202';public function __clone(){echo "调用了__clone()";}
}
$zerotwo=new Zerotwo();
$Franxx=clone($zerotwo);
__wakeup()函数漏洞原理:(反序列化漏洞CVE-2016-7124)
当序列化字符串表示对象属性个数的值 大于 真实个数的属性时就会跳过__wakeup的执行
正则匹配大写字母O后不能跟数字时,可在数字前加+号绕过
相关文章:
序列化和反序列化(一)
因为通过这段时间的学习,发现,序列化和反序列化的考点和漏洞在平时遇到的还是比较多的,而且自己也没有特别去学习过这个知识点,所以在这里写一篇关于这里序列化和反序列话的博客,废话就停止在这里了。 在介绍具体的序列…...
1小时放弃Rust(2): 两数之和
1. 目的 陈越姥姥说,ACM拿奖的人有两类,一类是 NOIP 搞了好几年的,另一类是大学才开始搞 ACM 但是专注度远超常人的人。 学习 Rust 大概也是需要高度的专注度。让我试一下 ACM 的入门题目 AB 吧! 2. 题目地址 https://leetcod…...
罗德与施瓦茨NRP33SN,一款独立、特性齐全的功率探头
罗德与施瓦茨NRP33SN功率探头概述 ROHDE & SCHWARZ NRP33S 三路二极管功率传感器 罗德与施瓦茨 NRP33S 三路二极管功率传感器是一款独立 、特性齐全的仪器。它们可以通过罗德与施瓦茨 NRP2 基 本单元、通过 USB 的笔记本电脑/PC 以及许多罗德与施瓦 茨仪器(例如…...
【GoF23种设计模式】02_单例模式(Singleton Pattern)
文章目录 前言一、什么是单例模式?二、为什么要用单例模式?三、如何实现单例模式?总结 前言 提示:设计者模式有利于提高开发者的编程效率和代码质量: GoF(Gang of Four,四人帮)设计…...
springboot452当代中国获奖的知名作家信息管理系统的设计与实现(论文+源码)_kaic
摘 要 计算机网络发展到现在已经好几十年了,在理论上面已经有了很丰富的基础,并且在现实生活中也到处都在使用,可以说,经过几十年的发展,互联网技术已经把地域信息的隔阂给消除了,让整个世界都可以即时通话…...
基于Redis的网关鉴权方案与性能优化
文章目录 前言一、微服务鉴权1.1 前端权限检查1.2 后端权限检查1.3 优缺点 二、网关鉴权2.1 接口权限存储至Redis2.2 网关鉴权做匹配 总结 前言 在微服务架构中,如何通过网关鉴权结合Redis缓存提升权限控制的效率与性能。首先,文章对比了两种常见的权限…...
FutureWarning: `clean_up_tokenization_spaces` was not set.
警告内容: "clean_up_tokenization_spaces was not set. It will be set to True by default. This behavior will be deprecated in transformers v4.45, and will be then set to False by default. For more details check this issue: https://github.com…...
卫星综合电子软件系统
微小卫星星载综合电子系统采用星上总线网络将星载功能模块互相连接,实现微小卫星平台的模块集成、资源重组优化以及内部信息共享和综合利用。综合电子系统是微小卫星的核心组成部分,是整星的信息和控制中心。 包括遥控遥测管理系统、载荷管理系统、 热控…...
M3D: 基于多模态大模型的新型3D医学影像分析框架,将3D医学图像分析从“看图片“提升到“理解空间“的层次,支持检索、报告生成、问答、定位和分割等8类任务
M3D: 基于多模态大模型的新型3D医学影像分析框架,将3D医学图像分析从“看图片“提升到“理解空间“的层次,支持检索、报告生成、问答、定位和分割等8类任务 论文大纲理解1. 确认目标2. 分析过程(目标-手段分析)核心问题拆解 3. 实…...
开源数字人系统源码短视频文案提取文案改写去水印小程序
应用场景 短视频去水印: 个人用户:在社交媒体上分享短视频时,去除原视频中的水印,以保护个人隐私或避免侵权问题。企业用户:在广告、宣传和营销活动中,使用无水印的短视频以提高品牌知名度和吸引力。 文案提…...
范德蒙矩阵(Vandermonde 矩阵)简介:意义、用途及编程应用
参考: Introduction to Applied Linear Algebra – Vectors, Matrices, and Least Squares Stephen Boyd and Lieven Vandenberghe 书的网站: https://web.stanford.edu/~boyd/vmls/ Vandermonde 矩阵简介:意义、用途及编程应用 在数学和计算科学中&a…...
CSSmodule的作用是什么
CSS Modules的作用主要体现在以下几个方面: 1. 解决全局样式污染问题 在传统的CSS管理方式中,样式定义通常是全局的,这很容易导致全局样式污染。当多个组件或页面共享同一个样式时,可能会出现样式冲突和覆盖的情况,从…...
winform中屏蔽双击最大化或最小化窗体(C#实现),禁用任务管理器结束程序,在需要屏蔽双击窗体最大化、最小化、关闭
winform中屏蔽双击最大化或最小化窗体(C#实现),禁用任务管理器结束程序,在需要屏蔽双击窗体最大化、最小化、关闭 protected override void WndProc(ref Message m){#region 处理点击窗体标题栏放大缩小问题,禁用点击窗体标题栏放大缩小//logger.Info($&…...
【Go系列】:全面掌握 Sentinel — 构建高可用微服务的流量控制、熔断、降级与系统防护体系
前言 在现代分布式系统架构中,服务的稳定性和可用性是至关重要的。随着微服务和云原生技术的发展,如何有效地进行流量控制、熔断降级以及系统保护成为了一个关键课题。Sentinel 是阿里巴巴开源的一款面向分布式服务架构的流量控制组件,它不仅…...
【图像分类实用脚本】数据可视化以及高数量类别截断
图像分类时,如果某个类别或者某些类别的数量远大于其他类别的话,模型在计算的时候,更倾向于拟合数量更多的类别;因此,观察类别数量以及对数据量多的类别进行截断是很有必要的。 1.准备数据 数据的格式为图像分类数据集…...
我的“双胞同体”发布模式的描述与展望
当被“激情”晕染,重创标题、摘要探索“吸睛”。 (笔记模板由python脚本于2024年12月19日 15:23:44创建,本篇笔记适合喜欢编撰csdn博客的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免…...
详细了解一下装饰模式
文章目录 装饰模式定义UML 图其主要优点包括:装饰模式的主要角色有:C 代码示例总结 装饰模式定义 动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式必生成子类更加灵活 装饰模式(Decorator Pattern&…...
MyBatis入门的详细应用实例
目录 MyBatis第一章:代理Dao方式的CRUD操作1. 代理Dao方式的增删改查 第二章:MyBatis参数详解1. parameterType2. resultType 第三章:SqlMapConfig.xml配置文件1. 定义properties标签的方式管理数据库的信息2. 类型别名定义 MyBatis 第一章&…...
23 go语言(golang) - gin框架安装及使用(四)
五、跨域资源共享 跨域资源共享(CORS,Cross-Origin Resource Sharing)是一种机制,它允许来自不同源的请求访问资源。默认情况下,浏览器出于安全原因会阻止跨域 HTTP 请求。Gin 框架本身没有内置的 CORS 支持ÿ…...
信息安全概论
文章目录 预测题重要考点1.遇到什么威胁有什么漏洞怎么缓解分析题2.网络安全现状分析 2.网络安全亮点 时间信息安全概论期末简答题软件学院实验室服务器安全风险分析与PDRR策略 1.1 信息时代的特点1.2 信息安全威胁1.3信息安全趋势1.4 研究网络与信息安全的意义2.1安全风险分析…...
深度学习的DataLoader是什么数据类型,为什么不可用来索引
在 Python 中,DataLoader是torch.utils.data.DataLoader类的实例对象,用于加载数据,它本身不是一种基本数据类型,而是一种特殊的迭代器类型,主要用于按批次加载数据,以下是其通常不可索引的原因:…...
2024最新qrcode.min.js生成二维码Demo
找了一堆代码一堆GPT,终于给写对了: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…...
python elasticsearch 8.x通过代理发起请求方法
由于python elasticsearch v8 engine的源码包中并未开放对于请求添加proxies的支持,导致在某些环境下无法连通外网的es服务。目前网上暂无相关的修改内容,我这边提供下自己修改的动态运行时替换elasticsearch包的源码方法demo import gzip import ssl i…...
android opencv导入进行编译
1、直接新建module进行导入,选择opencv的sdk 导入module模式,选择下载好的sdk,修改module name为OpenCV490。 有报错直接解决报错,没报错直接运行成功。 2、解决错误,同步成功 一般报错是gradle版本问题较多。我的报…...
Group FLUX - User Usage Survey Report
文章目录 User Feedback Summary: Software Advantages and FeaturesUser Feedback Issues and Suggested Improvements1. Security Concerns:Improvement Measures: 2. System Performance and Loading Speed:Improvement Measures: 3. Data Display Issues:Improvement Measu…...
门店全域推广,线下商家营销布局的增量新高地
门店是商业中最古老的经营业态之一。很早就有行商坐贾的说法,坐贾指的就是门店商家,与经常做商品流通的「行商」相对应。 现在的门店经营,早已不是坐等客来,依靠自然流量吸引顾客上门,大部分的门店经营与推广都已经开…...
【DevOps工具篇】Jenkins的Pipeline(流水线)和Shared Library(共通库)
【DevOps工具篇】Jenkins的Pipeline(流水线)和Shared Library(共通库) 文章目录 【DevOps工具篇】Jenkins的Pipeline(流水线)和Shared Library(共通库)Pipeline流水线[](#pipeline流水线)让我们在多分支上创建流水线[](#让我们在多分支上创建流水线)单分支与多分支流水线对…...
V900新功能-电脑不在旁边,通过手机给PLC远程调试网关配置WIFI联网
您使用BDZL-V900时,是否遇到过以下这种问题? 去现场配置WIFI发现没带电脑,无法联网❌ 首次配置WIFI时需使用网线连电脑,不够快捷❌ 而博达智联为解决该类问题,专研了一款网关配网工具,实现用户现场使用手机…...
网络安全:基线检查---自动化脚本检测.
基线定义 基线通常指配置和管理系统的详细描述,或者说是最低的安全要求,它包括服务和应用程序设置、操作系统组件的配置、权限和权利分配、管理规则等。 基线检查内容 主要包括账号配置安全、口令配置安全、授权配置、日志配置、IP通信配置等方面内容&…...
序列模型的使用示例
序列模型的使用示例 1 RNN原理1.1 序列模型的输入输出1.2 循环神经网络(RNN)1.3 RNN的公式表示2 数据的尺寸 3 PyTorch中查看RNN的参数4 PyTorch中实现RNN(1)RNN实例化(2)forward函数(3…...
JMeter配置原件-计数器
一、面临的问题: 由于本人的【函数助手对话框】中counter计数器每次加2,且只显示偶数(如下图所示),因此借助【配置原件-计数器】来实现计数功能。 如果有大佬知道解决方式,麻烦评论区解答一下,谢谢。 二、配置原件-c…...
JS子页面调用父页面函数,监听刷新事件
目录 1.子页面调用父页面的函数 2.监听刷新事件 1.子页面调用父页面的方法 我们先来说说什么是子页面,在我这里子页面就是域名一样,然后使用iframe引入的页面就是我所说的子页面,为什么需要用到这个功能,是为了实现跨页面交互与…...
计算机视觉(为天地立心,为生民立命)
4. 逻辑回归中,对数损失函数怎么来表示的? 5. relu激活函数它的一些特点? ReLU的数学表达式为:f(x)max(0,x) 特点: 1.简单高效:ReLU 的计算非常简单,直接将输入小于 0 的部分置为 0ÿ…...
三格电子——新品IE103转ModbusTCP网关
型号:SG-TCP-IEC103 产品概述 IE103转ModbusTCP网关型号SG-TCP-IEC103,是三格电子推出的工业级网关(以下简称网关),主要用于IEC103数据采集、DLT645-1997/2007数据采集,IEC103支持遥测和遥信,可…...
金碟中间件-AAS-V10.0安装
金蝶中间件AAS-V10.0 AAS-V10.0安装 1.解压AAS-v10.0安装包 unzip AAS-V10.zip2.更新license.xml cd /root/ApusicAS/aas# 这里要将license复制到该路径 [rootvdb1 aas]# ls bin docs jmods lib modules templates config domains …...
最新D音滑块JS纯算法还原(含完整源码)
文章目录 1. 写在前面2. 接口分析2. 源码实现【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作! 【🌟作者推荐】:对爬…...
接口绑定有几种实现方式
在 MyBatis 中,接口绑定是指通过 Java 接口与 SQL 映射文件(XML)进行绑定,允许你以面向对象的方式操作数据库。MyBatis 提供了几种不同的实现方式来实现接口绑定。 MyBatis 接口绑定的几种实现方式 基于 XML 映射的实现方式 这是…...
Oracle JDK需登录下载解决
JDK下载地址 地址:https://www.oracle.com/java/technologies/downloads/archive/ 登录账号获取 访问:https://bugmenot.com/view/oracle.com 直接复制账号密码登录下载...
LabVIEW与PLC点位控制及OPC通讯
在工业自动化中,PLC通过标准协议(如Modbus、Ethernet/IP等)与OPC Server进行数据交换,LabVIEW作为上位机通过OPC客户端读取PLC的数据并进行监控、控制与处理。通过这种方式,LabVIEW能够实现与PLC的实时通信,…...
VM16+解压版CentOS7安装和环境配置教程(2024年12月20日)
VM16解压版CentOS7安装和环境配置教程-2024年12月20日 一、下载安装包二、vm安装三、解压版CentOS7安装四、CentOS设置静态IP 因为很多同学觉得配置CentOS7好麻烦,我特地提供了一个已经配置好的现成镜像,来简化操作本篇来记录过程。 如果你在看到这篇文章…...
SQL中的约束
约束(CONSTRAINT) 对表中字段的限制 非空约束:NOT NULL 只能声明在每个字段的后面 CREATE TABLE test( id INT NOT NULL, last_name VARCHAR(15), phone VARCHAR(20) NOT NULL );唯一性约束:UNIQUE 说明: ① 可以声明…...
【Lua热更新】上篇
Lua 热更新 - 上篇 下篇链接:【Lua热更新】下篇 文章目录 Lua 热更新 - 上篇一、AssetBundle1.理论2. AB包资源加载 二、Lua 语法1. 简单数据类型2.字符串操作3.运算符4.条件分支语句5.循环语句6.函数7. table数组8.迭代器遍历9.复杂数据类型 - 表9.1字典9.2类9.3…...
数据压缩比 38.65%,TDengine 重塑 3H1 的存储与性能
小T导读:这篇文章是“2024,我想和 TDengine 谈谈”征文活动的三等奖作品之一。作者通过自身实践,详细分享了 TDengine 在高端装备运维服务平台中的应用,涵盖架构改造、性能测试、功能实现等多个方面。从压缩效率到查询性能&#x…...
Linux shell脚本用于常见图片png、jpg、jpeg、tiff格式批量转webp格式后,并添加文本水印
Linux Debian12基于ImageMagick图像处理工具编写shell脚本用于常见图片png、jpg、jpeg、tiff格式批量转webp并添加文本水印 在Linux系统中,使用ImageMagick可以图片格式转换,其中最常用的是通过命令行工具进行。 ImageMagick是一个非常强大的图像处理工…...
DeepFaceLab技术浅析(六):后处理过程
DeepFaceLab 是一款流行的深度学习工具,用于面部替换(DeepFake),其核心功能是将源人物的面部替换到目标视频中的目标人物身上。尽管面部替换的核心在于模型的训练,但后处理过程同样至关重要,它决定了最终生…...
怎么将pdf中的某一个提取出来?介绍几种提取PDF中页面的方法
怎么将pdf中的某一个提取出来?传统上,我们可能通过手动截取屏幕或使用PDF阅读器的复制功能来提取信息,但这种方法往往不够精确,且无法保留原文档的排版和格式。此外,很多时候我们需要提取的内容可能涉及多个页面、多个…...
imu相机EKF
ethzasl_sensor_fusion/Tutorials/Introductory Tutorial for Multi-Sensor Fusion Framework - ROS Wiki https://github.com/ethz-asl/ethzasl_msf/wiki...
CSDN数据大屏可视化【开源】
项目简介 本次基于版本3 开源 版本3开源地址:https://github.com/nangongchengfeng/CsdnBlogBoard.git 版本1开源地址:https://github.com/nangongchengfeng/CSDash.git 这是一个基于 Python 的 CSDN 博客数据可视化看板项目,通过爬虫采…...
C# 从控制台应用程序入门
总目录 前言 从创建并运行第一个控制台应用程序,快速入门C#。 一、新建一个控制台应用程序 控制台应用程序是C# 入门时,学习基础语法的最佳应用程序。 打开VS2022,选择【创建新项目】 搜索【控制台】,选择控制台应用(.NET Framew…...
什么是 DevSecOps 框架?如何提升移动应用安全性?
在如今数字化发展的时代,安全性已成为移动应用开发不可或缺的一部分。传统的开发模式通常将安全作为一个独立的部门,专门负责保护组织的整体系统,而 DevSecOps 框架则将安全融入到 DevOps 的每一个环节中,确保应用的开发、测试、发…...