BLE配对和绑定
参考:一篇文章带你解读蓝牙配对绑定
参考:BLE安全之SM剖析(1)
参考:BLE安全之SM剖析(2)
参考:BLE安全之SM剖析(3)
目录
- 前言
- 基本概念解读
- Paring(配对)
- Bonding(绑定)
- STK短期秘钥、LTK长期秘钥等
- Paring配对流程及命令
- 阶段1:配对特性交换Paring流程及命令
- 阶段2:密钥生成
- 阶段3:秘密信息分发
- 绑定,重连和加密
- 配对命令一览表
- 其他注意的点
前言
什么是低功耗蓝牙配对?什么又是绑定?配对和绑定有什么区别?配对有什么好处?如何删除绑定信息?如何确定配对的安全等级?just work的配对一定就不安全吗?如何开发自己的配对应用?本文将对以上问题进行论述。
Paring(配对)和bonding(绑定)是实现蓝牙射频通信安全的一种机制,有两点需要注意:
-
一是paring/bonding实现的是蓝牙链路层的安全,对应用来说完全透明,也就是说,不管有没有paring/bonding,你发送或接收应用数据的方式是一样的,不会因为加了paring/bonding应用数据传输需要做某些特殊处理;
-
二安全有两种选项:加密或者签名,目前绝大多数应用都是选择加密,后续我们也会以加密为重点进行讲述
实现蓝牙通信安全,除了paring/bonding这种底层方式,用户也可以在应用层去实现相同功能,两者从功能上和安全性上没有本质区别,只不过应用层自己实现的话,需要自己选择密码算法,密钥生成,密钥交换等,如果你不是这方面的专家,你的应用就有可能会存在安全漏洞。Paring/bonding则把上述过程标准化,放在了蓝牙协议栈中,并且其安全性得到了充分评估,用户可以 “无感的” 用上安全的蓝牙通信。
Paring/bonding是蓝牙security manager(SM)的一部分,SM定义了蓝牙通信的安全框架,里面涉及安全架构,密码工具箱,paring协议等,其中paring协议是关键,所以我们经常把paring和SM二者等价,下面将对paring进行详细阐述。
基本概念解读
Paring(配对)
配对包括配对能力交换,设备认证,密钥生成,连接加密以及机密信息分发等过程,配对的目的有三个:加密连接,认证设备,以及生成密钥。从手机角度看,一旦设备跟手机配对成功,蓝牙配置菜单将包含该配对设备,如下所示:
如果用户需要主动删除配对设备,点击配对设备右边的“设置”菜单,出现如下界面,选择“取消配对”或者“忽略该设备”,设备的配对信息即被手机删除。
Bonding(绑定)
配对过程中会生成一个长期密钥(LTK,long-term Key),如果配对双方把这个LTK存储起来放在Flash中,那么这两个设备再次重连的时候,就可以跳过配对流程,而直接使用LTK对蓝牙连接进行加密,设备的这种状态称为bonding。
如果paring过程中不存储LTK(不分发LTK)也是可以的,paring完成后连接也是加密的,但是如果两个设备再次重连,那么就需要重走一次paring流程,否则两者还是明文通信。
在不引起误解的情况下,我们经常把paring当成paring和bonding两者的组合,因为只paring不bonding的应用情况非常少见。在不引起混淆的情况下,下文就不区分paring和bonding的区别,换句话说,我们会把paring和bonding两个概念等同起来进行混用。
STK短期秘钥、LTK长期秘钥等
SM(security manager)
蓝牙协议栈的安全管理层,规定了跟蓝牙安全通信有关的所有要素,包括paring,bonding,以及下文提到的SMP。
SMP(security manager protocol)
安全管理协议,SMP着重两个设备之间的蓝牙交互命令序列,对paring的空中包进行了严格时序规定。
OOB(out of band,带外)
OOB就是不通过蓝牙射频本身来交互,而是通过比如人眼,NFC,UART等带外方式来交互配对信息,在这里人眼,NFC,UART通信方式就被称为OOB通信方式。
Passkey
又称pin码,是指用户在键盘中输入的一串数字,以达到认证设备的目的。低功耗蓝牙的passkey必须为6位。
Numeric comparison(数字比较)
Numeric comparison其实跟passkey一样,也是用来认证设备的,只不过passkey是通过键盘输入的,而numeric comparison是显示在显示器上的,numeric comparison也必须是6位的数字。
MITM(man in the middle)
MITM是指A和B通信过程中,C会插入进来以模拟A或者B,并且具备截获和篡改A和B之间所有通信报文的能力,从而达到让A或者B信任它,以至于错把C当成B或者A来通信。
如果对安全要求比较高,需要具备MITM保护能力,在SM中这个是通过认证(authentication)来实现的,SM中实现认证的方式有三种:OOB认证信息,passkey以及numeric comparison,大家根据自己的实际情况,选择其中一种即可。
LESC(LE secure connections)
又称SC,蓝牙4.2引入的一种新的密钥生成方式和验证方式,SC通过基于椭圆曲线的Diffie-Hellman密钥交换算法来生成设备A和B的共享密钥,此密钥生成过程中需要用到公私钥对,以及其他的密码算法库。
LESC同时还规定了相应的通信协议以生成该密钥,并验证该密钥。需要注意的是LESC对paring的其他方面也会产生一定的影响,所以我们经常会把LESC看成是一种新的配对方式。
Legacy paring
在LESC引入之前的密钥生成方式,称为legacy paring,换句话说,legacy paring是相对LESC来说的,不支持LESC的配对即为legacy paring(legacy配对)。
TK(Temporary Key,临时密钥)
legacy paring里面的概念,如果采用just work配对方式,TK就是为全0;如果采用passkey配对方式,TK就是passkey;如果采用OOB配对方式,TK就是OOB里面的信息。
STK(short term key,短期密钥)
legacy配对里面的概念,STK是通过TK推导出来的,通过TK对设备A和B的随机数进行加密,即得到STK。
LTK(long term key,长期密钥)
legacy配对和LESC配对都会用到LTK,如前所述,LTK是用来对未来的连接进行加密和解密用的。Legacy paring中的LTK由从设备根据相应的算法自己生成的(LTK生成过程中会用到EDIV(分散因子)和Rand(随机数)),然后通过蓝牙空中包传给主机。
LESC配对过程中,先通过Diffie-Hellman生成一个共享密钥,然后这个共享密钥再对设备A和B的蓝牙地址和随机数进行加密,从而得到LTK,LTK由设备A和B各自同时生成,因此LTK不会出现在LESC蓝牙空中包中,大大提高了蓝牙通信的安全性。
IRK(Identity Resolving Key,蓝牙设备地址解析密钥)
有些蓝牙设备的地址为可解析的随机地址,比如iPhone手机,由于他们的地址随着时间会变化,那如何确定这些变化的地址都来自同一个设备呢?
答案就是IRK,IRK通过解析变化的地址的规律,从而确定这些地址是否来自同一个设备,换句话说,IRK可以用来识别蓝牙设备身份,因此其也称为Identity information。IRK一般由设备出厂的时候按照一定要求自动生成。
Identity Address(设备唯一地址)
蓝牙设备地址包括public,random static, private resolvable,random unresolved共四类。
如果设备不支持privacy,那么identity address就等于public或者random static设备地址。
如果设备支持privacy,即使用private resolvable蓝牙设备地址,在这种情况下,虽然其地址每隔一段时间会变化一次,但是identity address仍然保持不变,其取值还是等于内在的public或者random static设备地址。
Identity Address和IRK都可以用来唯一标识一个蓝牙设备。
IO capabilities(输入输出能力)
是指蓝牙设备的输入输出能力,比如是否有键盘,是否有显示器,是否可以输入Yes/No两个确认值。
Key size(密钥长度)
一般来说,密钥默认长度为16字节,为了适应一些低端的蓝牙设备处理能力,你也可以把密钥长度调低,比如变为10个字节。
Paring配对流程及命令
Paring包含三个阶段:
-
阶段1:配对特性交换,即交换各自都支持哪些配对特性,比如支不支持SC,支不支持MITM,支不支持OOB,以及它的输入输出能力等。
-
阶段2:密钥生成阶段,legacy paring和LESC paring两者的区别就在这里,因此后续我们会分开阐述legacy paring和SC paring的阶段2。
Legacy paring:STK生成(注:legacy paring的LTK生成跟配对流程无关,如前所述,其是由从机自己生成的)
SC paring:LTK生成 -
阶段3:通过蓝牙空中包分发一些秘密信息。Legacy paring需要分发LTK,IRK等,而SC paring只需分发IRK。秘密信息分发之前,必须保证连接已加密。
Paring流程如下所示:
阶段1:配对特性交换Paring流程及命令
配对特性交换涉及三条PDU命令:
1、Paring_Request:
2、Paring_Response:
3、Security_Request:
°IO Capability占一个字节,其定义如下所示:
°AuthReq也是占用一个字节,其定义如下所示:
阶段2:密钥生成
°根据阶段1的IO输入输出能力以及是否存在OOB,阶段2存在如下几种配对方式(或者说认证方式):
- Just works
- Numeric comparison(LESC才有)
- Passkey
- OOB
对于legacy paring,如果A和B都支持OOB,那么两者就会采用OOB方式进行配对,否则根据IO能力选择配对方式。
对于SC paring,如果A或者B有一方支持OOB,那么两者就会采用OOB方式进行配对,否则根据IO能力选择配对方式。不同的IO能力对应的配对方式如下所示。
粗略来说,有认证的配对方式就具备MITM保护功能,从IO角度看,有三种配对方式:just works,passkey和Numeric Comparison,其中just works没有MITM保护功能,而passkey和Numeric comparison具备MITM保护功能。换句话说,如果你要求你的设备具备MITM保护功能,那么它必须有一定IO能力,而不能是“NoInputNoOutput”。至于OOB方式有没有MITM保护,取决于OOB通信的安全性,如果OOB通信具备MITM保护,那么蓝牙也具备MITM保护,否则就不具备。
下面分legacy paring和sc paring对配对流程进行讲解。
legacy paring
°Legacy paring整个配对流程是围绕STK生成来做的:
设备的认证是通过设备A和B经由TK生成一个确认数,如果这个确认数相同,则认证通过。
如前所述,legacy paring需要先生成TK,TK的生成方式取决于配对方式:
- Just works。TK默认为全0
- Passkey。TK由6位passkey扩展而来
- OOB。TK直接由OOB数据提供
°然后生成确认数,算法如下所示:
LP_CONFIRM_I = c1(TK, LP_RAND_I, Pairing Request command, Pairing Response command, initiating device address type, initiating device address, responding device address type, responding device address)
LP_CONFIRM_R = c1(TK, LP_RAND_R, Pairing Request command, Pairing Response command, initiating device address type, initiating device address, responding device address type, responding device address)
°生成STK的算法如下所示:
STK = s1(TK, LP_RAND_R, LP_RAND_I)
以passkey legacy paring为例,其第2阶段全工作流程如下所示:
Just works和OOB配对流程就不再赘述了,大家自己去看一下蓝牙核心规范的说明。
这里强调一下,配对完成之后,连接就会加密,而且加密的密钥是STK,而不是LTK。
对于legacy paring,如果A和B都支持OOB,那么两者就会采用OOB方式进行配对,否则根据IO能力选择配对方式。对于SC paring,如果A或者B有一方支持OOB,那么两者就会采用OOB方式进行配对,否则根据IO能力选择配对方式。不同的IO能力对应的配对方式如下所示。
LESC paring
°跟legacy paring不一样的地方:
LESC paring是通过Diffie-Hellman算法直接生成LTK,因此它不需要生成TK和STK。为了生成LTK,双方需要先交换公钥,流程如下所示:
- 公钥交换后,设备A和B就开始独自计算各自的DHKey,按照D-H算法,他们俩算出的DHKey会是同一个。而LTK和MacKey就是通过这个DHKey加密一系列数据而得到的。
- Legacy paring在整个配对流程中只做一次认证,而LESC paring会做两次认证。LESC第一阶段认证的原理是,设备A和B各生成一个随机数,然后认证这个随机数对不对。LESC第二阶段认证过程是:设备A和B通过MacKey各生成一个检查值,对方确认这个值对不对。
以LESC Numeric comparison为例,其第一阶段认证流程如下所示:
我们还是以LESC Numeric comparison为例,其第二阶段全工作流程如下所示:
一旦LTK生成成功,主机端就可以发起加密连接流程,如下所示:
至此,LESC连接被LTK加密了,后面就可以分发秘密信息了。
阶段3:秘密信息分发
°一旦连接加密了,主机和从机之间就可以分发一些秘密信息。如果是legacy paring,如下秘密信息必须分发:
- LTK
- EDIV
- Rand
°同时根据情况,legacy paring还需分发如下信息:
- IRK
- Identity adresss
对于LESC paring,秘密信息分发是可选,一般有可能分发如下信息:
- IRK
- Identity adresss
如下为legacy paring可能分发的最多秘密信息的一个例子:
绑定,重连和加密
如果配对的两个设备生成了LTK及其他秘密信息:
如上所述,如果配对的两个设备生成了LTK及其他秘密信息,并且把LTK及其他秘密信息保存到Flash等永久化存储设备中,那么我们就可以说这两个设备绑定成功。换句话说,paring和bonding是两个不同的概念,paring更强调认证和密钥生成,而bonding更强调密钥保存。
一旦两个设备bonding成功,那么这两个设备断开再次重连的时候,主机就可以发起加密流程,从而使用paring生成的LTK对后续的连接进行加密。主机发出加密连接流程如下所示:
这里说明一下,加密连接只能由主机发出,而不能由从机发起。不过从机可以发出加密请求,主机收到从机的加密请求后,可以发起加密连接也可以拒绝其请求。如下为主机同意从机的加密请求的工作流程:
配对命令一览表
如下为SM中用的PDU命令列表:
(注:加密连接命令属于LL控制命令,所以没有包含在其中)
其他注意的点
苹果手机的一点不同:
安卓手机允许用户手动发起paring请求,而苹果手机则没有这个功能。因此,即使你的characteristic没有使能安全级别,安卓手机还是可以跟你的设备完成配对的,而苹果手机则不支持这个功能,苹果手机要不要跟设备进行配对,不能由人来控制的,只能由苹果iOS来控制。
欲触发苹果iOS发起配对请求,有两种方法:
- 一是将某个characteristic加上安全认证权限,这样iOS在服务发现过程中就会自动发起配对请求,以满足characteristic的安全认证级别;
- 二是从机端主动发起安全请求,iOS收到从机的安全请求后,会等待用户的授权确认从而发起配对请求。这两种方法在ble_app_gls中都有体现,大家可以参考相关代码。
重连加密等级:
绑定成功后,如果发生重连,那么主机应该自动发起加密连接请求,以对连接进行加密。一般来说,在连接没有成功加密前,主从机不要做敏感数据的交互,否则softdevice API会报NRF_ERROR_FORBIDDEN。对于有MITM保护的加密连接,在收到PM_EVT_CONN_SEC_SUCCEEDED这个事件后,设备应该去检测连接的安全等级是否符合要求,具体可参考ble_app_gls例子的做法。
Service changed(服务改变):
设备跟手机绑定成功后,手机再次重连这个设备时,就会自动跳过service discovery过程,换句话说,配对的时候手机会把设备所有服务和characteristic的handle保存下来,二次重连的时候,直接用以前保存的 handle 值去操作设备。
但是,如果设备的服务改变了,此时手机再用之前的 handle 去操作设备,就会出问题。为了解决这个问题,在GATT主服务里面引入了 service changed characteristic,如下所示:
有了这个characteristic,当设备的服务发生改变时,设备就可以通过这个characteristic发送一个indicate PDU给到手机,从而手机知道设备的服务已发生了改变,此时手机会重新发起service discovery流程,以重新获得service和characteristic最新的handle列表。欲添加service changed characteristic,你只需在sdk_config.h文件中打开如下两个宏:
然后当服务发生改变时,调用pm_local_database_has_changed(),协议栈就会自动发起service changed indicate PDU给手机,从而引起手机重走服务发现过程。
删除主机端绑定信息:
如果手机端删除了绑定信息,为了安全起见,设备端也需要跟着一起删除绑定信息,否则手机无法再次跟设备进行配对,这个是最理想的情况,但是我们有的设备没有任何输入接口,无法手动删除绑定信息,这个时候能不能有一种办法可以让手机跟设备进行二次配对呢?
为此,Nordic提供了一种workaround,在蓝牙事件回调函数里面,加上如下代码即可:
if (p_evt->evt_id == PM_EVT_CONN_SEC_CONFIG_REQ) { pm_conn_sec_config_t cfg; cfg.allow_repairing = true; pm_conn_sec_config_reply(p_evt->conn_handle, &cfg); }
这样,即使用户把手机端paring信息删掉,设备端paring信息没有删掉,手机还是可以跟设备进行二次配对的。
删除从机端绑定信息:
跟上面相反,如果设备端 bonding 信息被删除了,而手机端 bonding 信息没有被删除,这种情况下如何实现二次配对?
最安全的方式,让用户主动删除手机端绑定信息,但是很多开发者希望,用户体验好一点,也就是说,碰到这种情况希望手机能自动删除绑定信息,这个能不能实现跟手机有很大关系,首先我们确保协议栈返回LL_REJECT_IND or LL_REJECT_EXT_IND,错误码为“PIN or key missing”,一般而言,手机收到这个PDU后,都会自动删除bonding信息。
如果上述方法行不通的话,那么发送完LL_REJECT_IND后再调用断开函数(sd_ble_gap_disconnect),同时将断开原因设为BLE_HCI_AUTHENTICATION_FAILURE即可。
同时绑定多个设备:
Nordic SDK是支持一个设备同时跟多个主机绑定,只要设备存储空间足够大,那么可以绑定的设备数就不设限。nRF5 SDK中bonding信息也是通过fds来存储的,也就是说绑定信息和用户Flash数据共享同一块空间,如果需要绑定多个设备,那么FDS_VIRTUAL_PAGES这个宏的值必须进行修改,以保证分配的Flash空间可以同时容纳bonding信息和用户Flash数据。
一般来说,如果需要绑定多个设备,请设置一个最大绑定数,比如8个,这样,一旦检测到绑定数达到8了,就可以把以前老的bonding设备删除,从而节省存储空间。那如何知道哪个设备是老设备哪个设备是新设备?这个是通过peer rank来实现的,大家只要使能PM_PEER_RANKS_ENABLED这个宏,就可以自动实现排序。
循环绑定测试:
很多开发者喜欢做循环绑定测试,即同一部手机不断跟同一个设备进行配对,然后删除配对信息,然后再进行配对,他们测试下来发现:
达到一定次数后,设备就工作不正常了,这个是由于当bonding信息不断累积而不进行删除的话,那么分配给fds的Flash空间就会耗尽,从而导致异常出现(最新的SDK会在Flash存储空间耗尽时,自动删除最老设备的绑定信息,但即使这样,对用户Flash数据的操作影响还是很大)。
解决这个问题的方法就是设定一个最大bonding数,达到这个数目后,删除老bonding信息,从而达到循环利用Flash空间的目的。当然如果你的fds只是用来存储bonding信息而不做其他用户数据操作的话,那么就没有必要加上这个功能了。
白名单与绑定:
虽然白名单和绑定二者没有任何联系,但是我们一般都把两者结合起来一起使用,以达到我们的使用期望。当两个设备绑定成功后,我们就可以将对方的mac地址或者IRK放入白名单中,同时开启白名单广播,这样设备只跟白名单中的主机进行连接,白名单以外的设备在controller层面就被过滤掉了,从而提高私密性以及连接效率。
这样,即使用户把手机端paring信息删掉,设备端paring信息没有删掉,手机还是可以跟设备进行二次配对的。
这种情况下,哪怕是合法的设备,如果之前没有跟设备绑定,那么它也无法跟设备建立连接。换句话说,如果你想把新设备加入到白名单中,那么首先需要禁止白名单广播而采用普通广播,然后跟新设备进行配对,成功后再把新设备身份信息加入到白名单中。白名单与绑定的例子具体可参考:ble_app_hids_keyboard。
Authenticated payload timeout:
大家都知道蓝牙连接有一个 supervision timeout 时间,也就是说,当建立连接的两个设备,任何一方在supervision timeout(比如4s)时间内,没有给对方发送任何蓝牙空口包,此时认为连接已断开,并触发 supervision timeout 事件。
当设备双方建立加密连接后,不仅有上述的supervision timeout,还有一个authenticated payload timeout,authenticated payload timeout默认为30s,它的意思是,两个设备加密后,30s内必须有一个有数据的空口包交互,而不能一直发空包,否则认为authenticated payload timeout。
Authenticated payload timeout是协议栈自动管理的,对软件开发来说是透明的,每30s时间到,如果期间没有任何有效数据包交互(一直在发空包),协议栈会自动发送一个ping request给对方,以避免authenticated payload timeout的出现(注:这里的协议栈既可以是设备的协议栈,也可以是手机的协议栈)。
有时候不想等到30s超时到了再发送ping request,大家可以在connected事件中,调用如下API以提前发出ping request。
当然,如果你能保证每30s时间内,手机和设备之间肯定会有有效数据包交互,或者手机端能及时准确地发出ping request,那么上述过程就完全没有必要了。
评论:你好,请问如果NRF52840和手机已经配对绑定了,手机如何下次自动连接呢?不通过nrf Connect App。就像一般蓝牙耳机一样。
回答:完成了绑定流程之后,手机端和设备端会存储对方的信息密钥。后面收到设备的广播后,手机会自动发起回连的,信息和密钥验证成功后,就回连成功了。
相关文章:

BLE配对和绑定
参考:一篇文章带你解读蓝牙配对绑定 参考:BLE安全之SM剖析(1) 参考:BLE安全之SM剖析(2) 参考:BLE安全之SM剖析(3) 目录 前言基本概念解读Paring(配对)Bonding(绑定)STK短期秘钥、LTK长期秘钥等 …...

无涯教程-jQuery - html( val )方法函数
html(val)方法设置每个匹配元素的html内容。此属性在XML文档上不可用。 html( val ) - 语法 selector.html( val ) 这是此方法使用的所有参数的描述- val - 这是要设置的html内容。 html( val ) - 示例 以下是一个简单的示例,简单说明了此方法的用法- <…...

【单链表OJ题:删除链表中等于给定值 val 的所有节点】
1.删除链表中等于给定值 val 的所有节点 题目来源 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 /*** Definition for singly-linked list.* struct ListNode {* int val;* s…...

vue element ui web端引入百度地图,并获取经纬度
最近接到一个新需要,要求如下: 当我点击选择地址时,弹出百度地图, 效果如下图: 实现方法: 1、首先要在百度地图开放平台去申请一个账号和key 2、申请好之后,在项目的index.html中引入 3、…...

25.10 matlab里面的10中优化方法介绍—— 函数fmincon(matlab程序)
1.简述 关于非线性规划 非线性规划问题是指目标函数或者约束条件中包含非线性函数的规划问题。 前面我们学到的线性规划更多的是理想状况或者说只有在习题中,为了便于我们理解,引导我们进入规划模型的一种情况。相比之下,非线性规划会更加贴近…...

赛效:如何将PDF文件免费转换成Word文档
1:在网页上打开wdashi,默认进入PDF转Word页面,点击中间的上传文件图标。 2:将PDF文件添加上去之后,点击右下角的“开始转换”。 3:稍等片刻转换成功后,点击绿色的“立即下载”按钮,将…...

java 8 的Stream API
Java 8中引入了Stream API,它是一种处理集合数据的新方式,可以用来处理集合中的元素。Stream API通过提供一组函数式接口和方法,可以使集合的处理更加简洁、高效和易读。 Stream API的主要特点如下: 延迟执行:Stream …...

TypeChat,用TypeScript快速接入AI大语言模型
TypeChat是C# 和 TypeScript 之父 Anders Hejlsberg全新的开源项目。使用AI在自然语言和应用程序和API之间建立桥梁,并且使用TypeScript。 现在出现了很多大型语言模型,但是如何将这些模型最好地集成到现有的应用程序中,如何使用人工智能来接…...

Dcoker compose单机容器集群编排管理
目录 一、概述 二、compose 部署 lnmp 1.Docker Compose 环境安装 2.YAML 文件格式及编写注意事项 3.Docker Compose配置常用字段 4.Docker Compose 常用命令 5. 配置lnmp集群依赖文件 6.修改docker-compose.yml文件 7.根据yml文件创建lnmp容器 一、概述 Docker compos…...

P5635 【CSGRound1】天下第一(记忆化搜索)
用short类型二维数组防止MLE。这里用的记忆化搜索,如果f[x][y]已经有值了,直接返回这个值。判断error的方法:如果下一次又访问到它,说明出现了循环,这样是永远%不到0的,所以,第一次访问一次f[x]…...

如何维护你的电脑:提升性能和延长使用寿命
如何维护你的电脑:提升性能和延长使用寿命 😇博主简介:我是一名正在攻读研究生学位的人工智能专业学生,我可以为计算机、人工智能相关本科生和研究生提供排忧解惑的服务。如果您有任何问题或困惑,欢迎随时来交流哦&…...

Docker续集+Docker Compose
目录 Containerd与docker的关系 runCrunC与Containerd的关联 OCI协议Dockerfile多阶段构建(解决:如何让一个镜像变得更小 )多阶段构建Images瘦身实践.dockerignore Docker Compose快速开始Quick StartCompose 命令常用命令命令说明 Compose 模…...

k8s deployment(k8s经典版)|PetaExpress
Deployment是什么? Deployment是指在软件开发中将应用程序或系统部署到目标环境中的过程。它包括将代码编译、配置、打包并安装到目标服务器或设备上的步骤。k8s deployment是(k8s经典版)中用来管理发布的控制器,在开发的过程中使…...

uni-app如何生成正式的APK
第一步: 进入dcloud官网https://dcloud.io/,点击开发者后台进入登录注册页面 第二步:登录之后跳到项目列表,选择自己想要打包的项目 点击进去如果没有生成证书,点击生成证书,如果显示证书已生成就不用管了…...

低代码开发平台源码:可视化敏捷开发工具,拖拽式自定义表单界面
低代码开发平台源码 低代码管理系统源码 无需代码或通过少量代码就可以快速生成应用程序的开发平台。 本套低代码管理后台可以支持多种企业应用场景,包括但不限于CRM、ERP、OA、BI、IoT、大数据等。无论是传统企业还是新兴企业,都可以使用管理后台快速构…...

利用读时建模等数据分析能力,实现网络安全态势感知的落地
摘要:本文提出一种基于鸿鹄数据平台的网络安全态势感知系统,系统借助鸿鹄数据平台读时建模、时序处理、数据搜索等高效灵活的超大数据存储和分析处理能力,支持海量大数据存储、分类、统计到数据分析、关联、预测、判断的网络安全态势感知能力…...

六、代理模式
文章目录 一、代理模式1、代理模式的好处和缺点1.1 代理模式理解加深 一、代理模式 为什么要学习代理模式? 代理模式是Spring AOP 以及 Spring MVC 的底层!!并且还是 JAVA 的23种设计模式之一!! 代理模式的分类&#…...

Easy Glide
题意:给出起点终点坐标,然后给出可以经过的几个点,未经过这几个点的时候以v1的速度前进,一旦经过这些点就可以在3秒内以v2的速度前进,3秒之后恢复v1,问从起点到终点所需的最短时间 思路:最短路…...

ppt怎么压缩到10m以内?分享好用的压缩方法
PPT是一种常见的演示文稿格式,有时候文件过大,我们会遇到无法发送、上传的现象,这时候简单的解决方法就是压缩其大小,那怎么才能将PPT压缩到10M以内呢? PPT文件大小受到影响的主要因素就是以下几点: 1、图…...

VBA技术资料MF35:VBA_在Excel中过滤数据
【分享成果,随喜正能量】好马好在腿,好人好在嘴。不会烧香得罪神,不会讲话得罪人。慢慢的你就会发现,一颗好心,永远比不上一张好嘴。。 我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了&#…...

Debian12中为python3配置虚拟环境及在Pycharm中使用虚拟环境
在Debian 12中,python默认为python 3.11。 基于应用,现需设置虚拟环境。 1.安装venv模块 从python3.3开始,配置python虚拟环境,可用venv模块,更加方便了。 执行命令: #apt install python3.11-venv 2.…...

android app控制ros机器人一
android开发app,进而通过控制ros机器人,记录开发过程 查阅资料: rosjava使用较多,已经开发好的app也有开源的案例 rosjava GitHub https://github.com/ros-autom/RobotCA https://github.com/ROS-Mobile/ROS-Mobile-Android…...

二十章:基于弱监督语义分割的亲和注意力图神经网络
0.摘要 弱监督语义分割因其较低的人工标注成本而受到广泛关注。本文旨在解决基于边界框标注的语义分割问题,即使用边界框注释作为监督来训练准确的语义分割模型。为此,我们提出了亲和力注意力图神经网络(A2GNN)。按照先前的做法&a…...

webpack5 学习之路
1.视频 01-课程介绍_哔哩哔哩_bilibili 2.配套资料 依赖环境 | 尚硅谷 Web 前端之 Webpack5 教程 3.webpack 官方文档 入口起点(entry points) | webpack 中文文档 4.vue cli 官方文档 介绍 | Vue CLI 挖矿:Coding Tree...

VSCode C++ 调试方法
VSCode 调试 C 主要就是 .vscode 中的 launch.json 和 tasks.json 的配置。 launch.json 可以通过 vscode 界面 ——》左侧调试功能按钮——》创建 launch.json ——》C(GDB/LLDB)生成。 其中 launch.json 默认配置如下,主要配置项说明&…...

Java设计模式-命令模式
命令模式 1.命令模式含义 命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。对请求排队或记录请求日志,以及支持可撤销的操作。 命令模式乍一看,有点懵懵的。即使这个定义看完,也是不明…...

Linux编译宏BUILD_BUG_ON_ZERO
本系列文章主要写我在阅读Linux内核过程中,关注的比较难以理解但又设计巧妙的代码片段(不关注OS的各个模块的设计思想,此部分我准备写在“深入理解Linux Kernel”系列文章中),一来通过内核代码复习一下C语言及汇编语言…...

从Arweave开始:4EVERLAND存储签入挑战开始
嗨,4evers, 今天,我们热烈欢迎您参加 Galxe 上的 4EVERLAND “Arweave 入门”活动。这是一项长期的重头活动,所有参与的用户都有机会获得相应的奖励。 Arweave 是一种革命性的去中心化存储协议,为寻求安全可靠的有价…...

数据结构—链表
链表 前言链表链表的概念及结构链表的分类 无头单向非循环链表的相关实现带头双向循环链表的相关实现顺序表和链表(带头双向循环链表)的区别 前言 顺序表是存在一些固有的缺陷的: 中间/头部的插入删除,时间复杂度为O(N)…...

windows 10/11 修改右键新建菜单
问题:修改右键新建菜单内容 解决方法:使用软件ShellNew Settings 1.打开软件 2.根据需要取消勾选项 3.最终效果...