首页 > 其他分享 >BLE中SMP的配对原理分析

BLE中SMP的配对原理分析

时间:2023-06-01 18:22:38浏览次数:50  
标签:加密 蓝牙 Alice SMP 密钥 BLE Bob 配对

蓝牙SMP层中的配对原理分析

本文作为蓝牙SM协议的学习笔记,大部分内容取自于网上资料(密码学知识)和蓝牙核心规范。阅读需要有一定的蓝牙技术知识和密码学知识基础

密码学基础

基本的安全问题

在通信中,安全问题至关重要,基本的安全入侵手段包括窃听、伪装和篡改。假设:

Alice和Bob分别是两家银行,Bob银行通过网络向Alice银行发送了一条500元的汇款请求:从账户B-6789向账户A-1234汇款500元

当然,会有人在网络中尝试攻击银行间通信,妄想用非法手段牟利,其中就有这样一个分工明确的组织,由以下成员组成:

  • Eve
    • 窃听不同银行之间的消息,从中获取重要信息,如获知“从账户B-6789向账户A-1234汇款500元”。
  • Mallory:
    • 篡改不同银行之间的消息,如修改汇款请求为“从账户B-6789向账户A-1234汇款5000000元”。
    • 伪装成Bob银行,以Bob银行名义发送一条新的汇款请求给Alice银行。

从上述例子可知消息面临的威胁有:窃听、篡改和伪装,对应的安全特性为:机密性、一致性、是否已认证。

“威胁”和“安全特性”的关系可以这样描述:

  • 如果消息没有加密,消息则不具有机密性,无法防止他人窃听;
  • 如果发送者发送的消息和接收者的消息是不同的,说明消息被篡改过,不具有一致性;
  • 如果没有对消息进行认证,无法保证消息来自正确发送者而不是伪装者。

存在威胁,就会有对应的解决方法,下面会针对每个威胁介绍对应的密码技术。

密码技术

对称加密技术

算法一般指复杂步骤,加密算法指的是用明文生成密文的步骤,解密的步骤称为解密算法,两者统称为密码算法,密码算法需要用到密钥。

所谓对称密码(symmetric cryptography)技术,即加密和解密时用的是同一个密钥,加密和解密的算法一般是公开的,但是密钥是私有的,由用户自己掌握。

例如上图所示,A和B共同协商好一个密钥,但E不知道密钥是多少。当A使用密钥将信息加密传递给B时,B可以用密钥解析出来。但E没有密钥就无法解析,窃听到了信息也不知道什么意思。一般比较出名的对称加密算法有AES128。

对称加密技术可以解决窃听问题,并且加解密效率高,在目前社会各方面广泛使用。但是他有两个问题

1、密钥需要Alice和Bob预先协商好,而且不能直接使用当前有被窃听风险的渠道进行传递确认。例如一开始Alice和Bob并没有协商好密钥,而是在刚开始通信时,由Alice自己定一个密钥,然后传给了Bob。假如这个刚开始过程被Eve窃听到了密钥是什么,那么Eve就可以解析密文了。

2、无法抵御伪装攻击,例如Eve虽然不知道密文什么意思。但他可以记录下,然后重复发给Alice。Alice收到数据误以为还是Bob发的,而且能够解密,便又进行了多次汇款。

这种也叫重放攻击。

非对称加密技术

随着时代的发展,数学家们找到了一种新的密码算法。他的特点在于和对称加密技术相比,区别加密时用的密钥和解密时的密钥不一样,并且能够解决上述对称加密技术的第二个密钥传递泄露的问题。算法具体的原理这里不作解释,但我们可以举个例子来说明为什么这个特点能解决密钥泄露。

例如上图所示,Alice根据非对称加密技术生成了一组加密密钥和解密密钥。他将加密密钥通过公开渠道传给了Bob,同时Eve也窃听到了这个加密的密钥。Bob手上有加密密钥,可以加密手上的信息发给Alice,Alice有解密的密钥,可以解密Bob的信息。而Eve没有解密的密钥,即便偷听到了Bob的密文也无法解密。

这样一来,只要Bob也想Alice一样生成一组对应的密钥,只把加密密钥给对方,自己留着解密密钥。那Alice和Bob就可以随意给对方发信息而不用担心被窃听了。

这里我们把公开传递的加密密钥叫做公钥,自己保留的解密密钥叫做私钥。目前常见的非对称加密算法有RSA算法,Diffie-Hellman (D-H)算法, 椭圆DH算法。

非对称加密技术可以解决对称加密算法中的密钥传递问题,但是他也有两个比较主要问题

1、效率低,非对称算法的加解密速度要比对称的低十几倍,不适合大量数据传输。

2、无法抵御篡改和伪装攻击。假设Eve直接下场,把Alice和Bob发给对方的公钥都截留,然后再伪装成对方,将Eve自己的公钥发送过去。这就导致Alice和Bob都误以为手上是对方的公钥钥,实际都是Eve的公钥,发给对方的信息都能被Eve窃听篡改。这种叫中间人攻击(Man-in-the-MiddleAttack,简称MITM)

消息认证码技术

为了解决篡改攻击,数学家们又找到了一种叫做消息认证码(Message authentication code,缩写为MAC)的技术。这项技术的关键在于通过对信息使用密钥进行加密得到一个特殊的校验码(不是密文),在信息交互时把该校验和也一起传递。

例如上图所示,Alice和Bob和对称加密时那样预先商量好一个校验密钥,当Alice使用该密钥把信息的校验和算出来后,再把信息和校验和一起发给Bob。Bob也用密钥把消息的校验和算一遍,确认是Alice发的一样才认为是合法的。而Eve没有校验密钥,篡改信息,因为如果Eve篡改信息,会因为算不出对的校验和和被Bob验证失败,篡改校验和也是同理,只要得到校验密钥将信息和校验和一起篡改才能成功。

MAC技术和加密算法技术最大的区别在于只加密(或者说校验),不作解密。而且算法在理论上也无法根据消息和校验和反推得到校验和,这保证了只要Eve不知道校验密钥就没办法算校验和。另外他的加密效率高,输入敏感,冲突概率小,能很好的解决篡改问题。

但他还是有两个主要问题:
1、密钥需要先协商好,这点和对称加密一样。

2、能避免篡改,对伪装问题有一定保护,通过验证码保护,Eve没办法直接下场假冒Alice和Bob跟对方通信。

MAC技术可以解决MITM攻击,但还是无法解决重放攻击。那么重放攻击该怎么解决呢,根据网上资料,一般有如下方案:

  • 加随机数。该方法优点是认证双方不需要时间同步,双方记住使用过的随机数,如发现报文中有以前使用过的随机数,就认为是重放攻击。缺点是需要额外保存使用过的随机数,若记录的时间段较长,则保存和查询的开销较大。
  • 加时间戳。该方法优点是不用额外保存其他信息。缺点是认证双方需要准确的时间同步,同步越好,受攻击的可能性就越小。但当系统很庞大,跨越的区域较广时,要做到精确的时间同步并不是很容易。
  • 加流水号。就是双方在报文中添加一个逐步递增的整数,只要接收到一个不连续的流水号报文(太大或太小),就认定有重放威胁。该方法优点是不需要时间同步,保存的信息量比随机数方式小。但是一旦攻击者对报文解密成功,就可以获得流水号,从而每次将流水号递增欺骗认证端。

对付重放攻击除了使用本以上方法外,还可以使用挑战一应答机制和一次性口令机制,而且似乎后面两种方法在实际中使用得更广泛。这里因为这些与密码学无关,只是一些检查机制,故不作细讲,不过可以知道,只需通过将MAC技术和这些技术融合起来,便能实现对MITM和重放攻击的保护。

总结

  • 为了解决窃听问题,采用对称密码技术;
  • 为了解决对称密码技术的加密密钥配送问题,采用非对称加密技术;
  • 为了解决篡改问题,采用消息认证码技术;
  • 为了解决伪装问题,采用消息认证码技术;
  • 为了解决消息认证码技术的认证密钥配送问题,采用非对称加密技术。

对称加密和消息验证码加起来可以解决窃听、篡改、伪装问题,但是没办法解决密钥同步问题,需要用非对称加密来传递密钥。

非对称加密可以安全传递密钥,但其先验条件又要用消息验证码来解决伪装篡改问题。

两者成了蛋生鸡要先鸡生蛋的死循环,因此还是需要通过第三方方案来解决密钥同步的问题。最简单的还是人和人口耳相传,或者其他。

这样看好像非对称加密技术有些多余,最后还是要通过其他渠道来传递密钥才能保证身份认证安全,不能在通信时就把密钥给同步了。但其实不然,在后续的蓝牙协议规范中会提及到,非对称加密最大的作用其实是用于窃听之后解决暴力破解的。

蓝牙配对

配对的方法

配对在蓝牙SM协议中的重要部分,本质是同步通信时使用的对称加密密钥的一个过程。这个过程有多种方法可以进行建立,我们称之为配对的方法。4.2以前的版本用的配对方法称之为legacy配对,在蓝牙4.2版本后,蓝牙协议在原本的配对方法基础上,进行了重大版本更新,新增一种叫Secure Connections(后简称SC)配对。两者最大的区别在于SC配对引入了椭圆曲线Diffie-Hellman算法,而legacy没有。

这里我们先不管什么legacy,sc配对。我们从蓝牙最原始的手机与手机点对点无线通信为例,分析蓝牙配对技术的发展是怎么走到今天这一步的。

早期方法

最原始的蓝牙是没有加密的,报文都是明文传输,后来人们觉得不行,这样做不安全,于是开始想办法加上安全管理协议,对报文进行加密,这就是最早的需求。一开始人们想到加密方式是对称加密方式,双方协商好加解密密钥后,对报文进行加密通信。这个方法前面介绍过,关键点在于如何进行密钥协商。

蓝牙协议的设计者们最开始想到的方法让像拿银行卡在柜员机取钱那样,通过输入密码来进行解决密钥传递的问题。我们还是以Alice和Bob两个人为例,Alice想要拿手机传一些资料文件给Bob,但资料有些敏感,他不想被Eve看到。

这里出现了第一个问题,一般对称加密算法,要求的密钥太长了。例如AES128算法,密钥要输128bit长度,让用户自己想一个一起输入到手机里肯定不现实。为了简便蓝牙协议想了个办法,让用户输入一个六位数的密码来代替冗长的密钥,再通过一系列算法把这个六位数转成128bit的AES密钥。

这里相当与用安全换效率,六位数密码从000000-999999一共一百万个数,看上去很多,但用穷举法暴力破解还是很快的。

stage 1:

现在,开始进行配对流程。首先由Alice跟Bob说我要和你配对

这里相当与Alice发起配对请求(pairing request),成为initiator。Bob响应配对请求(pairing respond),成为responder响应者。

Bob接收到请求,随后使用随机数发生器随机生成一个六位数的密码(或者固定一个也行),再告诉给Alice。

这里Bob是通过人口耳相传来告诉Alice,而不是使用蓝牙传递密钥。

Alice收到这个六位数字后,通过公开算法生成一个128bit的数,我们叫做temporary key(临时密钥,简称TK)用于后续的加密流程。同样的,Bob在生成六位密码的同时,也会根据公开算法生成和Alice一样的TK。双方TK都生成后,会通知对方自己已经生成TK,随后进入下一个阶段。

有人可能会问直接用TK做报文的加密密钥不就好了了么?前面说过,六位密码容易被暴力破解,根据它生成的TK也是不够安全的。为此我们要把TK再处理以下,提高他的复杂度。

stage 2:

首先,Alice会用随机数生成器生成一个随机数,叫Mrand(主机的随机数),并用Mrand和TK以及其他一些如设备地址,配对请求指令等参数通过公开算法算出一个确认值叫做Mconfirm。同样Bob也会生成一个Srand(从机随机数)和Sconfirm。双方随机数和确认值都生成好后,双方交换这些参数。

先是Alice把Mconfirm发给Bob,然后Bob把Sconfirm发给Alice。随后Alice把Mrand发给Bob,bob收到后会用Mrand自己算一遍Mconfirm看看和Alice前面发的一不一样,一样就会把自己的Srand发给Alice,让Alice也算一遍确认下。此举目的在于确认双方TK是否一致,简单来讲就是在对暗号。但要注意的是这里的随机数和确认值交换是公开的,有被窃听到的风险。

Mconfirm = c1(TK, Mrand, 
Pairing Request command, Pairing Response command,
initiating device address type, initiating device address, 
responding device address type, responding device address)

Sconfirm = c1(TK, Srand, 
Pairing Request command, Pairing Response command, 
initiating device address type, initiating device address,
responding device address type, responding device address)

TK确认一致,双方认证成功。然后双方再用TK(之前生成的)、Mrand和Srand三个数,通过公开算法算出真正用于密文加密的密钥short term key(短期密钥,简称STK)。该STK就直接用来作为AES对称加密的密钥使用。至此,最原始的配对方法就完成了,这种方式我们称之为Passkey Entry方式。

\[STK = s1(TK, Srand, Mrand) \]

通过前面密码学知识,我们可以看到这种方式能够提供防窃听的保护,而且天然的带有一定的认证能力,能够一定程度上保证不会被攻击者伪装。但是这种最原始的配对流程还是有很多问题存在的,最主要的有两个:

1、要双方的设备至少有一方支持显示功能(用于显示六位密码),另一方支持输入功能(输入六位密码)。如果设备输入输出能力(IO capabilities)有限,那么就没办法走这套流程了。

2、随机数和confirm交换阶段如果被窃听到,那么安全性会大大降低。攻击者一样最多算100w次就能把TK算对。

这里我们先研究第一个问题怎么解决,再研究第二个问题怎么解决。

早期方法的衍生

针对第一个设备输入输出能力的问题,蓝牙协议的设计这边又想了其他两者方法

1、如果配对双方IO能力有限,没办法输密码。那么干脆在原来Passkey Entry方式的基础上,双方直接定死六位密码全为0或者1234,然后在这个基础上,双方继续走流程生成STK,然后进行加密通信。这种方式我们叫做Just work(简易)方式。

可以说这种方法毫无保障可言,既不能防止窃听,也不能放置篡改伪装。只要窃听者窃听到了TK建立过程,要破解是分分钟的事。唯一的作用就是让蓝牙通信不是明文传递。虽然不是裸奔,但也只是穿上了件透明衣服罢了。

2、如果设备有除蓝牙以外的通信能力,例如带有NFC、或者wifi。那么可以直接通过这些通道来传递密钥,不再通过人来口耳相传,再手敲键盘。这种方式我们叫做Out of band(带外)方式。

带外指的是蓝牙频带以外,常用的是NFC方式。OOB方式首先要求选用的通信方法本身足够安全,在这个基础上可以实现传递比六位数密码更复杂的密钥,防御性能更佳。这种配对方式自由化程度很高,没有同一的标准流程,需要根据实际情况来分析,例如汽车钥匙应用上有专门一套CCCR规范来定义。

这里我们看到后续的衍生方案只是针对IO输入输出能力做的补充,对于整体的加密方案并没有本质上的改动。直到蓝牙4.2版本,新的方案才被提出来。

新时代的方法

在蓝牙4.2版本规范中,提出了一种新的配对方案,称之为security connect,而前面的那套方案则称为legacy(传统)方案。SC方案和legacy方案最大的区别,就是针对前面第二个问题点,随机数和确认值交换这一过程,进行了改进。不再使用明文传递,而是使用非对称加密中的椭圆DH算法来进行。

在SC配对中,Alice输入六位密码后,不再生成TK,而是先通过非对称加密算法生成自己的公钥和私钥。然后明文交换公钥,自己保留私钥。然后用双方用自己的私钥和对方的公钥算出共享密钥DHKey,用于后续生成对称加密的密钥使用。这里把Alice和Bob生成的公钥叫做PKa和PKb,私钥叫SKa和SKb。

DHkey你可以看作是Alice和Bob通过非对称加密方法传递的一个共享数据。通过前面的知识我们知道,公钥可以明文交换,但没有私钥即使被窃听也没办法破解,故DHkey无法被第三方窃听。但是非对称加密无法解决伪装问题,因此下一步我们需要通过使用前面输入的六位密码来进行认证。

接下来alice和bob使用同样的算法把六位密码拆成20个1bit的单独数据,分别为(ra1-ra20)和(rb1-rb20),随后再各自生成20个随机数(Na1-Na20)和(Nb1-Nb20)。然后alice把这20个1bit密码跟自己生成的随机数一一对应,和公钥一起通过公开算法算出验证码(Ca1-Ca20),即Cai=f(PKa,PKb,Nai,rai)。同理Bob也生成20个Cbi。

这里和legacy的用随机码和TK值生成confirm过程本质是一样的,只是将TK换成了20个分割的1bit数据,随机码也对应增加20个不同的,同时算法入参去掉以前的设备地址和配对指令这些信息,而是换成非对称加密的密钥。

Alice和Bob各自生成自己20个认证码后,逐一交换确认码Cxi和对应的随机数Nxi,Alice每发一组对应的确认码和随机数,Bob便计算校验一遍。校验成功则回发自己的这组确认码和随机数,一旦有验证不对的情况,立即终止配对过程。直到双方认证码都交换验证完毕,双方也就确定对方的六位密码是否和自身的一样了。确认一致后,双方把随机数Na20设置为Na,Nb20设置为Nb,用于下一阶段的对称加密密钥生成。

这样做的目的是把以前一次就能完成的确认值匹配(也就是对暗号过程)分成了20次,每次只对1bit的信息。哪怕被攻击,一次也只是泄露1bit数据。这个说法在蓝牙规范里叫做gradual disclosure(逐步披露),目的是增加暴力破解的难度。该过程完成后,认证过程结束,DHKey是可信任的,可以用于后续生成对称加密的密钥使用。

这里ra和rb就是原始的六位密码,正常情况两个数应该是一样的。其中3-8的步骤会重复20次,每次验证原始密码的1bit。

在验证成功后,双方再使用之前得到的随机数Na、Nb、设备地址A、设备地址B、和DHKey,算出用于对称加密的密钥的Long term key(长期密钥,简称LTK),和用于MAC消息认证码的校验密钥MacKey。

这里六位密码也不用于作为密钥的生成,仅仅用于身份验证,确保不会被伪装攻击,取而代之的是使用更为安全的DHKey来生成对称加密密钥。另外再用于防篡改的MAC校验密钥MACkey也一同生成传递。

最后再把所有参数混合算出最后的验证码Ea和Eb,做最后的验证同步。至此,基本的配对结束,Alice和bab使用LTK作为对称加密来作为密钥,使用MacKey作为消息校验码的密钥。实现了防窃听、篡改、伪装的目的。

新时代方法的衍生

基于SC方案,针对IO能力蓝牙协议在原来的三种方案上又衍生出一种新方案,叫做Numeric comparison(数字比较),numeric comparison其实跟passkey一样,也是用来认证设备的。只不过passkey是要用户得知密码后手动输入,再由蓝牙设备自己做验证。而数字比较则是由蓝牙设备直接把密码传输到配对方,然后显示在屏幕上,由用户自己来确认对不对。

这种方式与其说是密码,不如说是配对码。同样的,配对码也是六位数字。得益于使用非对称加密技术,配对码在使用蓝牙传输时不会被窃听到,因此只能在SC方案中使用。

总结

通过上述分析,我们可以对蓝牙的配对原理做出基本的总结了。基于密钥技术使用上的不同,分为legacy和SC两者方式,两者流程的大概区别如下:

对比下来毫无疑问是SC方案更好更安全,非对称加密技术的引入大大提高了legacy方案抵御暴力破解的能力。新增的消息码认证技术可以保护信息不被恶意篡改。

随后再根据IO能力,我们再进一步总结出目前蓝牙的四种配对方法:

防MITM攻击能力 设备IO能力要求
Just Works 无法抵御MITM攻击 不需要额外的输入输出设备
Passkey Entry 能抵御MITM攻击 需要有基本的屏幕显示、键盘输入能力
Numeric Comparison(不支持legacy) 能抵御MITM攻击 需要有基本的屏幕显示、键盘输入能力
Out of Band 取决于带外通信的安全性 需要带外通信能力

配对的流程

实际上,前面分析的只是大概的流程。实际上的规范流程要正式的多,并且会多一些细节上的完善。这里我不想对协议一字一句的翻译,只会大概说明下。只要能掌握前面的流程分析,基本就能对整个配对原理了然于胸。

实际的配对流程分为三个阶段:

第一阶段:Pairing Feature Exchange

该阶段主要是交换通信双方的IO能力和配对要求,以确定后续要实现哪一种配对流程。

配对能力交换的内容如下:

  • IO capabilities:输入输出能力
  • OOB authentication data availability:带外认证是否可用
  • authentication requirements:认证要求
  • key size requirements:密钥长度要求
  • which transport specific keys to distribute:选择何种密钥分发

前三项决定了实际要采取的配对流程:

  1. 如果两个设备都支持SC配对,则采用下图规则来决定下一步的抉择。

  1. 如果两个设备至少有一个设备不支持SC配对,则采用下图规则来决定下一步的抉择。

  1. 其中IO能力与配对方法的映射关系如下图所示

第二阶段:STK/LTK Generation

第二阶段则是生成用于对称加密密钥的过程,在前面章节已经介绍过passkey方法的STK/LTK密钥生成原理,这里就不再赘述了。其他方式和passkey本质上没有太大区别,有兴趣的可以再去翻白皮书仔细了解。

第三阶段: Transport Specific Key Distribution

通过第一、第二阶段,整个蓝牙其实已经可以在加密过的安全链路上进行工作了。第三个阶段其实只是在已经加密好的链路上,再交换一些其他用途的密钥罢了。这些密钥中主要有四个比较重要的密钥:

  1. Identity Resolving Key (IRK):一个128bit的密钥,用于生成或者解析随机地址。

例如苹果设备的蓝牙Mac地址是时不时就随机变化下的,这种设计的目的是为了保护设备。但是为了设备断连后,已经配对过的能够直接重连,跳过配对流程。需要能解析这个随机地址,让双方设备明白是已经配对过的设备地址。

  1. Connection Signature Resolving Key (CSRK):链接签名解析密钥,作用和IRK一致。只是这个密钥是用于解决签名验证。
  2. LTK:这里的LTK就是前面阶段生成的LTK。
  3. Encrypted Diversifier (EDIV) :16bit的密钥,用于识别在legacy配对期间分发的LTK。每次分发一个唯一的LTK时,都会生成一个新的EDIV。
  4. Random Number (Rand):65bit随机数,用于识别在legacy配对期间分发的LTK。

对于3、4、5点要额外说明下。其实legacy方法也会生成LTK,如果配对双方把这个LTK存储起来放在Flash中(以及另外两个EDIV和RAND),那么这两个设备再次重连的时候,就可以跳过配对流程,而直接使用LTK对蓝牙连接进行加密,设备的这种状态称为绑定(bonding)。

总结

其实到这里,我们应该对配对有了更深入的了解了,配对本质是一个建立加密密钥的过程,一个我们要协商出一个不会被窃听,不会被破解的密钥。同时也是一个认证流程,一个证明你是你,我是我的流程。

标签:加密,蓝牙,Alice,SMP,密钥,BLE,Bob,配对
From: https://www.cnblogs.com/simpleGao/p/17449860.html

相关文章

  • 解决 NVIDIA Windows has stopped this device because it has reported problems. (C
    场景当跑需要使用GPU算力的一些项目时候,需要用到CUDA,确保电脑是具有独立显卡的机子,但是怎么也没法让代码中的torch跑在GPU上;点击任务管理器查看"性能"下的GPU选项,看到运行中的并非是独立显卡而是集成显卡;点击设备管理器,发现NVIDIA显卡左下角有感叹号,双击发现里面显示......
  • Java开发手册中为什么禁止使用BigDecimal的equals方法做等值比较已经为什么禁止使用do
    场景阿里Java开发手册嵩山版中明确指出:1、BigDecimal的等值比较应使用compareTo()方法,而不是equals()方法equals()方法会比较值和精度(1.0与1.00返回结果为false),而compareTo()则会忽略精度2、禁止使用构造方法BigDecimal(double)的方式把double值转换为BigDecimal对象BigDeci......
  • Blender导出的模型和kanzi坐标轴匹配的设置方法
    1、blender里的导出配置 要改成Y向上,Z向前。 2、kanzi里摄像机的参数归0,然后导入的模型 各项参数也都归0,这样调整的角度就都是一致的。 ......
  • MySQL 8错误日志出现"The table /home/work/mysql_3306/tmp/#sqla2b_298b06_4d is fu
    ##############    了解MySQL8.0.26的错误日志出现"Thetable /home/work/mysql_3306/tmp/#sqla2b_298b06_4disfu11!"的bug,暂时通过修改临时表的存储引擎为内存引擎解决  MySQL8.0.13开始引入新的临时内存表引擎TempTable,并将其作为内存中创建临时表的默认存......
  • isDebugEnabled()
     if(log.isDebugEnabled()){log.debug("Nameis"+dealwithsomething());} 优先计算参数假如dealwithsomething()耗时较长但loglevel是info 则会造成低效如果一开始就判断log是info就会跳过这个耗时较长的方法提高了执行效率......
  • 重装系统蓝屏INACCESSIBLE_BOOT_DEVICE
    INACCESSIBLE_BOOT_DEVICE蓝屏解决方案好久没有用的电脑,系统打不开了,直接PE安装,出现蓝屏;重新安装了N此,依旧蓝屏;PE系统里面能识别到硬件,说明硬件没有问题;在网上查询了各种答案,不能解决;换官方原版镜像,解决问题!!!因为之前的镜像使用很多次,都没有问题;没有想到换镜像;换了之后,直......
  • AtCoder Beginner Contest 247 Ex Rearranging Problem
    洛谷传送门AtCoder传送门考虑我们如何判定一个排列是否能成为最终答案。连边\(i\top_i\),设环数为\(k\),那么最少交换次数为\(n-k\)。那么充要条件是,每个环所有点的\(c_i\)相同,并且\(n-k\leK\)且\(2\mid(K-(n-k))\)。\(K\)和\(n-k\)奇偶性相同是因为,......
  • inetsw table
    /*Theinetswtablecontainseverythingthatinet_createneedsto*buildanewsocket.*/staticstructlist_headinetsw[SOCK_MAX];staticDEFINE_SPINLOCK(inetsw_lock);for(q=inetsw_array;q<&inetsw_array[INETSW_ARRAY_LEN];++q)......
  • iOS蓝牙BLE4.0通信功能
    概述iOS蓝牙BLE4.0通信功能,最近刚学的苹果,为了实现蓝牙门锁的项目,找了一天学习了下蓝牙的原理,亲手测试了一次蓝牙的通信功能,结果成功了,那么就把我学习的东西分享一下。详细一、蓝牙常见名称和缩写BLE:(Bluetoothlowenergy)蓝牙4.0设备因为低耗电BLE:(Bluetoothlow......
  • 解决fatal: unable to access ‘https://github.com……‘: Failed to connect to
    问题:gitclone时会报如下错误 解决办法:1.在cmd下执行 ipconfig/flushdns,清理DNS缓存 2.重新执行gitclonehttps://github.com/.../.git即可成功......