The-MIFARE-Hack-1 -mifare技术

news2024/11/16 16:37:10

RFID卡的使用变得越来越普遍。 一般来说,使用两种类型的RFID卡:有源卡和无源卡。 主动系统有自己的能源,而被动系统则依赖读卡器提供的能量。 最常见的 RFID 卡之一是 MIFARE Classic,由 NXP Semiconductors(以前是 Philips 的一个部门)生产。 他们的总部位于荷兰埃因霍温。 恩智浦占据所有交通卡 75% 的市场份额,并且有超过 650 个城市使用基于 MIFARE 技术的交通卡,恩智浦显然是该技术的市场领导者。 [2] MIFARE Classic 卡系列不仅涵盖公共交通,还涵盖门禁管理、会员卡等,提供不同类型的卡,这些卡都是无源的,完全符合 ISO/IEC 14443 A 类标准。 [19 ] 出于加密目的,MIFARE Classic 卡使用 CRYPTO1 密码。 这是由 NXP 开发的专有加密算法。 该算法基于 HITAG2 算法,该算法用于 HITAG RFID 系统。 算法的细节由制造商保密。 这种方法被称为“通过模糊实现安全性”,并不是实现安全性的好方法[15]。由于试图保守算法的秘密,来自柏林混沌计算机俱乐部(CCC)的黑客 Nohl 和 Plotz 被 能够通过逆向工程(重新工程)发现算法。[14]本文展示了他们使用哪些步骤来重新设计算法,以及既然算法及其弱点已为公众所知,那么哪些攻击是可能的。

2 MIFARE

MIFARE Classic 卡有两种常见类型:MIFARE Classic 1k 和 4k。 1k 芯片具有 1k EEPROM 存储器,分为 16 个扇区和 4 个块,每个块包含 16 个字节。 这样总共有 64 个块。 4k 版本提供 4k EEPROM 存储器,分为 256 个块,其中 32 个扇区有 4 个块,另外 8 个扇区有 16 个块,如图 1 所示。 [16] 第一个块包含该设备的唯一标识号 (UID)。 卡以及一些受写保护的供应商特定数据。 在每个扇区的最后一个块上,可以找到访问密钥和访问规则。 该块不用于存储用户数据。 [16][17] 在允许对某个扇区进行任何内存操作之前,读取器必须针对该扇区验证自身身份。 因此,使用扇区尾部,其中包含用于认证的密钥A和B。 位于同一块中的访问条件指定该扇区上允许哪些内存操作。 [4][17] 对于扇区预告片本身,有特定的访问条件。 如前所述,预告片包含两个密钥 A 和 B。虽然密钥 A 永远不可读,但密钥 B 可以配置为可读或不可读。 如果声明为可读,则只有密钥 A 可以用于身份验证,密钥 B 将用于存储数据。 还有单字节 U,它没有明确的用途。 [4][16] 数据块用于存储应用程序的信息。 例如,在自助餐厅卡上,这可能是所有者的姓名加上卡的当前余额。

3 重新设计MIFARE Classic 3.1 选择卡和方法1 2006 年左右,德国柏林的“混沌计算机俱乐部”(CCC)开始研究MIFARE Classic 卡。选择这种特殊类型卡的原因是显而易见的。 :这一次,该卡使用了专有算法来进行加密,尽管这种方法在过去已经被证明是不安全的。原因是这些专有算法大多不需要经过外部第三方的检查 生产公司检测缺陷。另一个动机是芯片不安全,因为加密密钥只有 48 位长。这在 1994 年芯片发布时可能就足够了,但到了 1999 年, DES被破解,它使用56位密钥。选择这些特定芯片的最后一个原因是它过去和现在都是市场份额最高的RFID芯片系列[2]。与其他制造商相比,MIFARE标签和阅读器也很容易 可用,这减轻了调查的难度。 在 CCC 开始重新设计之前,最有效的已知攻击是简单的暴力攻击。 由于算法未知,因此必须直接针对卡完成此操作。 卡本身不会记住最后一分钟失败尝试次数等值。 这是因为卡的电源仅由读卡器提供,写入 EEPROM 会花费太多时间。 在这种情况下执行此类攻击的主要问题是持续时间。 尝试一个攻击键大约需要 5 毫秒。 考虑到 48 位密钥,需要长达 55,000 年才能找到正确的密钥。 将整个过程转移到计算机上会大大减少持续时间,但由于该算法不为公众所知,这是不可能的。 由于这些原因,有必要重新设计算法。 之前,算法已经通过反汇编被揭示。 因此,示例包括负责保护 GSM 通信安全的 A5/1 和 A5/2 算法 [1],以及用于汽车远程控制的 Hitag2 和 Keeloq 算法 [3]。 但这些都是软件实现,可以用固件、二进制文件或其他软件重新设计。 对于MIFARE芯片,没有软件实现。 所有计算均在硬件中完成。 另一种选择是黑盒分析。 使用这种方法,各种输入被发送到卡,并分析输出。 之前也曾通过黑盒分析成功进行过重新设计,但 MIFARE 的问题在于 48 位密码,这使得很难正确猜测算法中使用了哪些操作。 CCC 面临的下一个问题是,如果使用错误的密钥,该卡将不会应答。 根据 Henryk Plótz 的说法,这是 MIFARE Classic 卡中为数不多的精心设计的东西之一。 使用该系统,读卡器首先必须向卡验证自己的身份,表明它知道密钥。 否则,如果卡首先向读卡器验证自身身份,则必须向读卡器发送数据。 如果读卡器不知道密钥,则可以通过这种方式从卡中获取有价值的信息。 综上所述,软件的分析在不存在的情况下是不可能的,黑盒分析需要太多的运气。 但仍然有执行算法的硬件。 因此团队决定直接分析硬件

3.2 从硬件到算法2
重新设计的过程始于自助餐厅使用的 MIFARE Classic 卡。 这是一张预订卡,这意味着它的唯一目的是收取余额并用该余额付款。 在第一步之前,必须要指出的是,RFID 卡与 RFID 芯片不同。 该卡由一个微小的芯片组成,芯片周围有塑料,可将其扩展到信用卡大小。 因此,首先,CCC 需要从塑料中取出芯片。 要去除塑料,有两种可能性。 其中之一是使用丙酮。 作为替代方案,可以使用红发烟硝酸。 但因此,需要一个实验室,因为它操作起来很复杂。 为了保持较低的复杂性,选择了丙酮溶液。 要跳过此步骤,也可以直接购买芯片。 这可以为公司提供构建自己的卡的选择。 塑料溶解后,留下尺寸约为1x1mm的硅片。 这种芯片由不同的层组成。 就 MIFARE Classic 而言,芯片有七层。 为了分析这些层,使用了带有摄像头的标准显微镜,可将记录的图像直接发送到计算机。 这种显微镜的费用约为 1000 欧元。接下来,重新设计人员面临着只能看到芯片第一层的问题。 其他层可能会稍微透过第一个层,但这不足以执行完整的分析。 因此,第二步需要一种分析芯片所有层的方法。 因此,一种选择是化学蚀刻。 作为替代方案,可以对芯片进行机械抛光,这是 CCC 选择的方式。 与之前的步骤一样,原因是为了保持尽可能低的复杂性。 抛光时使用抛光乳液和0.04μm极细粒度的砂纸。 [14] 在这一步中,问题是需要对芯片进行均匀的抛光,以便能够清楚地看到所有层。 芯片本身甚至没有天线和其他连接的电线。 另外,其尺寸约为1平方米,徒手操作也很困难。 因此,CCC 决定在芯片周围放置塑料块。 有了这个,他们不仅有了一个更容易处理的物体,而且也更容易一层一层地打磨,因为即使在一侧也可以轻松制作块

抛光过程非常缓慢,必须非常小心地进行。 不可能恢复之前对芯片进行过抛光的任何内容。 需要分析的每一层厚度约为 1μm。 团队总共浪费了大约 10 个芯片才能获得所需的所有图片。 Henryk Plotz 猜测整个过程,包括学习过程,大约需要两周的时间。 但这个数字只是估计值,因为这项工作是在闲暇时间完成的,而不是在专业水平上完成的。 CCC制作完所有图层的图片后,下一步就是分析和重建它们的逻辑。 总共大约有 10,000 个门需要分析。 幸运的是,那些门的种类只有七十种左右。 为了加速分析,该团队创建了一个 MATLAB3 脚本,该脚本需要一个门作为输入,然后在芯片上的其他任何地方找到门,即使它们是旋转的。 该脚本同时以“\degate”[18] 的名称发布。最后,此过程会生成芯片概述,显示在哪个位置使用了哪种类型的门。此外,所有发现的门及其图片都已公开 列于网站“The Silicon Zoo”[13]。 图 2 显示了使用 \degate" 之前和之后芯片的图像。[14]。

在下一步中,团队手动跟踪门之间的所有连接。 每层大约有 100 个水平连接和 100 个垂直连接。 由于数量巨大,分析整个芯片需要花费太多精力。 因此,团队专注于加密逻辑,该逻辑仅占芯片的 10%。 为了确定芯片的哪个部分负责加密逻辑,上一步中创建的门图非常有用,因为可以分析门的分组。 例如,异或门和触发器门基本上仅用于密码学。 如果芯片上有一个地方显示出此类门的累积,则很有可能形成密码逻辑。 当发现 48 个异或门彼此相邻时,这表明团队在芯片上找到了正确的位置,考虑到 MIFARE Classic 的密钥也是 48 位长。 密码逻辑由大约 1000 个门和 1500 个连接组成。 为了对这些进行分析,团队跟踪了每个连接,记下哪个连接结束于何处以及哪个输入与哪个输出相关。 这个过程非常耗时,例如连接有时会跨越三个不同的层,或者也可能在整个芯片上运行。 因此,它也很容易出错,并且需要花费很多时间。 总的来说,重新设计过程的这一步又花了大约两周的时间。 重新设计的最后一步创建了一个电路图,从中可以创建一个框图,显示加密过程。 于是,投入了两年的闲暇时间,重新设计了MIFARE Classic卡的加密算法。 将在3.4节中详细解释。

3.3 初始化过程
现在,MIFARE Classic 卡的算法已被重新设计,唯一缺少的是初始化过程,因此缺少算法的初始状态,因为它不是加密逻辑的一部分。 该过程通过测试无线电协议来确定,这将在本节中讨论。 为了测试初始化过程,CCC 使用 OpenPCD 作为读取器。 这是一款免费的可编程 RFID 读取器,可以很好地控制发送和接收的数据。 [8] 来自荷兰“Radboud University Nijmegen”的其他研究人员使用 Proxmark III [5] 来窃听读卡器和卡之间的通信。该工具由 Jonathan Westhues 开发。如前所述,卡不会给出 如果使用错误的密钥进行授权,则给出答案。这是卡的良好设计,这导致了重新设计人员的更多工作。因此,在发现初始化过程的第一阶段,正确的密钥是 发送到卡上,然后逐位修改发送的数据,检查是否还有响应,通过切换各个位,发现UID和密钥被用作初始化的输入。 ,这一发现并不是什么大新闻,因为他们掌握的 MIFARE 文档中也提到了这一点。从芯片的重新设计中,我们知道密码逻辑只有一个输入。但因为他们也知道 有 UID 和密钥用作输入,这两者必须以某种方式连接起来。 也许连接方法是XOR,但这只是怀疑。 为了证明这个理论,UID 的第一位以及密钥的第一位都被翻转。 如果它们通过 XOR 连接,则仍应产生相同的值。 作为对团队的确认,该卡再次响应,这意味着通过异或连接的理论是正确的。 经过测试,他们发现UID的前5位和密钥是直接相连的,也就是说UID的第n位和密钥的第n位相连。 对于其他位,关系有所不同。 有关这些关系的更多信息可以在[16]中找到。 测试无线电协议期间的另一个发现是该算法使用伪随机数生成器(PRNG),它是通过线性反馈移位寄存器(LFSR)实现的。 一般来说,LFSR 创建一系列看起来彼此不同的数字。 它始终以相同的数字开始,并以相同的频率移动到下一个数字。 此外,一个 LFSR 的第 n 个数字将始终相同。 有关 LFSR 的更多信息可以在 [9] 中找到。 在无源 RFID 标签中使用 LFSR 所产生的一个问题是卡依赖于读卡器的供电。 这意味着,每次从读卡器中取出卡时,它都会断电,一旦再次获得能量,LFSR 就会重新启动其初始化序列,以与上次相同的频率发送相同的数字。 这一点在CCC的实验中得到了证明。 他们将卡放在读卡器旁边,然后打开读卡器。 因此,在卡被供电并开始创建随机数之后,读卡器开始通信的时间总是大约相同。 在此实验中,他们在 27 次尝试中有 12 次具有相同的 LFSR 随机值。 [16] 甘斯等人。 承认了这一弱点。 他们声称每小时能够生成大约 600,000 个随机值,其中随机数至少重复四次。 这意味着理论上随机值可能会在 0.618 秒后重新出现 [4]。 因此,发现了 MIFARE Classic 卡的第一个可能的攻击,即重放攻击。 对这种攻击的更详细的解释可以在第 4.2 节中找到。

3.4 算法
通过 CCC 所做的工作,现在可以详细介绍 MIFARE Classic 卡的 CRYPTO1 算法。 如图3所示,该算法由LFSR和函数f(x)组成。 [12] 首先,使用密钥初始化移位寄存器。 然后,PRNG 创建 32 位并将它们与 UID 进行异或。 然后该字符串将被移入移位寄存器[16]的状态。 创建的随机值还用于读卡器和卡之间的质询响应协议[10]。 此时,加密被激活,所有传入和传出位都与密钥流进行异或。 移位寄存器本身仅用于包含数据或循环冗余校验(CRC)值的位。 为了加密奇偶校验位,再次使用密钥流中已经用于数据位的位。 [16] 每个周期,函数 f(x) 都会从 LFSR 获得的 20 位中计算密钥流的一位。 LFSR 的 18 个抽头用于填充每个移位的第一个寄存器位。 为此,抽头是线性连接的。 由于这种线性连接,更新函数不包含任何非线性,这意味着当给定一个移位值时,攻击者可以计算先前的值以及即将到来的值。 以当今对加密系统的了解,这可以被认为是一个严重的弱点。 [14][17]

4 可能的攻击

本节展示了由于 CRYPTO1 密码、初始化和弱 PRNG 已为公众所知而可能发生的攻击。 除了提到的攻击之外,还存在其他可能性,例如权限升级、密钥流转移以及各种仅卡攻击。

4.1 暴力破解

在 CRYPTO1 算法为公众所知之前,最好的攻击是对卡进行简单的暴力破解。 其中,这是可能的,因为卡不安全状态,如错误验证尝试的数量。 这一次,由于卡没有自己的能源供应,这需要在芯片上进行写入过程,这会花费太多时间。 不记住失败登录尝试次数并在一定数量后锁定卡的另一个原因是,这将是另一种攻击可能性。 攻击者只需站在持有 RFID 卡的人旁边,只要卡锁定,就尝试使用随机密钥进行身份验证,从而执行拒绝服务 (DoS) 攻击 由于暴力破解只能直接针对卡进行,因此尝试一种方法 单键大约需要6ms。 密钥有 48 位。 这意味着尝试每种可能的组合大约需要 55,000 年。 [17] 该算法为公众所知后,荷兰组织 TNO 猜测,建造一台机器在两小时内破解 MIFARE Classic 密钥将花费约 9000 美元[22]。 根据CCC的说法,这个估计太多了,普通的PC应该足以在可接受的时间内破解密钥。 [17]

4.2 回放

重放攻击基于 MIFARE Classic 卡中使用的弱 PRNG。 一旦卡靠近读卡器,它就会接收电力并开始生成随机值。 这里的问题是 LFSR 总是以相同的频率生成相同的值,这意味着在卡通电后的时间 tn 时,PRNG 生成的随机数将始终相同。 [16][17] 如果攻击者现在窃听阅读器和标签之间的通信,则可以计算出标签激活后的时间 tn 开始通信。 当攻击者拥有标签时,甚至不需要知道确切的时间。 猜测正确时间的可能性很高就足够了。 [16] 攻击者现在可以在卡通电后的同一时间重播交易,并将获得相同的随机数。 作为替代方案,也可以更改交易。 这是可能的,因为没有执行完整性检查。 [16][17] 在许多情况下这可能会很有趣。 例如,当被窃听的通信增加预订卡的余额时,例如“将 e 5 添加到卡的当前余额”。然后可以根据需要多次重播此交易以增加余额。另一种可能的情况是 重播身份验证,如[4]所示

4.3 “幽灵”设备

荷兰“奈梅亨拉德堡大学”开发了一种名为“Ghost”的设备,这是一种可编程的RFID标签。 与普通标签一样,它能够与阅读器进行通信。 但与普通标签不同的是,设备上使用的微芯片是可以编程的。 Verdult 还编写了一个固件,允许控制读取器和标签之间发送的完整通信字节。 该设备使用 RS232 [21] 接口,能够与计算机的串行端口进行通信。 [6][23] 使用\Ghost",可以克隆RFID标签。首先,用户可以配置UID。然后,用户可以定义一些接收到的字节和随后发送的字节以设置反应 当从阅读器接收到某些帧时,这可能会很有用。根据 Verdult 的说法,当阅读器只想识别标签并因此请求一个未加密的简单答案时,这可能很有用。[23] 设备配置后 ,它可以与计算机断开连接并作为独立设备使用。这可以用于重放攻击。如果攻击者知道阅读器和标签之间的通信,则他可以使用“\Ghost”来克隆它。 [23] 除此之外,还可以使用该设备完成中间人(MITM)攻击。 因此,需要原始标签和阅读器、OpenPCD阅读器和连接到计算机的“Ghost”。设备所做的就是与原始阅读器通信并将请求转发到计算机。在那里,请求通过 OpenPCD 到原始标签。当标签应答时,它会应答 OpenPCD 阅读器,后者将数据发送到计算机。此数据被转发到“Ghost”,后者将它们发送回原始阅读器。 该场景如图4所示。[23]

在所描述的场景中,可以操纵从原始读取器发送到原始标签的数据。 因此,原因之一是读取器和标签均未检查接收到的数据的完整性。 [17]

4.4 密钥流恢复

Gans、Hoepmann 和 Garcia [4] 展示了另一种攻击。 这个也是基于弱PRNG的。 甘斯等人。 使用 Proxmark III 多次创建相同的随机数,这也会自动产生相同的密钥流。 由于相同的密钥流通过 XOR 与数据连接两次,因此如果已知另一个明文,则可以读取与密钥流连接的一个明文。 [4] 如果攻击者记录了包含读取命令的交易,他可以重放该交易,但更改应该读取的块。 为了获得已知的明文,使用了 MIFARE Classic 卡访问权限的特殊属性:密钥 A 永远无法读取。 如果有人试图读取它,卡将返回 0。 当密钥 B 用作密钥而不存储数据时(大多数情况都是这种情况),密钥 B 也是如此。 [4][17]

因此,当操作在时间 tn 完成时,卡返回 6 个字节的 0,与密钥流 kn 进行异或。 当攻击者现在也在卡通电后的时间 tn 读取另一个块时,该块使用相同的密钥流 kn 加密,然后由卡发送。 如果现在对从卡接收到的两条消息进行异或运算,则会丢弃密钥流 kn,因为使用相同的值进行两次异或运算会得到起始值。 剩下的是 6 个字节的 0 和一些未知文本,它们与第二个块的明文进行异或。 现在已知第一条消息开头包含 6 个字节的 0,因此可以读取第二个块的前 6 字节明文,如图 5 所示。 [4][17]

4.5 恢复密钥

加西亚等人。 他们在论文中提供了两次攻击,利用这些攻击,他们能够在一天或更短的时间内计算出 MIFARE Classic 卡的密钥。 [7] 对于他们的第一次攻击,他们在在线和离线搜索中分割了 48 位密钥。 首先,他们离线创建一个表,其中包含 LFSR 的状态和相关密钥流的前 64 字节。 这样的表可以在标准硬件上在一个下午内计算出来,并且需要大约 1 TB 的空间。 为了重复攻击,可以再次使用该表。 [6][7] 创建表后,该小组会与在线部分的读者创建 212 个身份验证会话。 对于每个会话,它们都会计算接下来的 64 位密钥流。 这不需要访问标签,只需要访问阅读器。 如果现在在线和离线部分使用相同的密钥流,则可以查找密码的内部状态。 为了随后计算密钥(等于 LFSR 的初始状态),只需向后运行密码即可达到该初始状态。 [7] 加西亚等。 他们声称,在一秒钟内,可以记录与阅读器的 5 到 35 次身份验证会话,具体取决于它是在线阅读器还是离线阅读器。 因此,收集攻击所需的所有 212 个身份验证会话将需要 2 到 14 分钟,其中攻击者需要住在读卡器旁边。 [7] Garcia 等人开发的另一种攻击。 al 花费的时间甚至更少,也可以在[7]中找到。 这种攻击依赖于团队能够反转 CRYPTO1 算法的函数 f(x) 的事实。 这种可逆性允许他们在身份验证结束时恢复 LFSR 的状态。 之后,与第一次攻击类似,他们计算回到初始状态。 使用这种攻击,他们只需要一个身份验证会话,而之前提到的攻击则需要 212 个身份验证会话。 [7] 据该团队称,实施这种攻击需要不到一秒的时间和几兆字节的 RAM 来恢复密钥。 与本节中的第一个攻击相反,这个攻击也不需要任何预计算工作。 甚至可以优化实现,使用相同的硬件将揭示密钥所需的时间降低到 0.1 秒以下。 Nohl 还开发了一种在一分钟内恢复密钥的方法,他在 [12] 中对此进行了解释。 与其他恢复密钥的攻击类似,该攻击也是基于攻击 LFSR。

5 后果

当第一个漏洞为公众所知时,恩智浦委托荷兰组织 TNO 来反证这些漏洞。 在 TNO 的以下报告中,发现的漏洞得到了承认,但该组织并未发现其中存在重大风险。 [22] 在越来越多的漏洞和攻击被发布后,NXP 决定发布他们的新 RFID 标签 MIFARE Plus。 根据 CCC [14] 的建议,新卡不再使用专有加密密码,而是使用高级加密标准 (AES)。 除此之外,新标签还支持MIFARE Classic。 这提供了从旧标签慢慢迁移到新 MIFARE Plus 标签的可能性。 [17] 在他们的网站上,恩智浦还发布了他们为确保 RFID 卡安全而开展的活动列表。 其中包括一个法庭案件,试图禁止荷兰集团公布他们的调查结果,这在[6]中有更详细的描述。 该列表可以在 [20] 中找到。 与此同时,许多公司将他们的MIFARE Classic卡更换为MIFARE DESFire,MIFARE DESFire比MIFARE Classic卡提供更好的硬件和更好的安全功能。 在传输方面,荷兰 OV Chipkaart 已更换为提供更好的 PRNG 以及针对侧信道攻击的保护的卡。 与其他卡(例如用于伦敦公共交通的伦敦牡蛎卡)类似,计划升级到不同的系统,但仍在进行中。 [17] 为了改善未来的发展,openticketing.eu基金会已经成立,荷兰部门正在推进开放密码设计和通信标准的使用以及公司与学术界的更密切合作。 [6] 再次证明,“通过模糊实现安全性”是不可行的。与其通过保密来保证加密算法的安全,不如利用已知、经过测试和接受的公共加密标准,例如 AES 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何强化九小场所安全检查隐患排查工作

九小场所与人们的日常生活息息相关,相关部门对这些场所的消防安全非常重视;但是由于各种原因,经营者安全意识薄弱,导致存在严重的安全隐患。凡尔码开发的九小场所巡检系统针对九小场所基数大、底数不清、责任不明、主体意识薄弱等…

Python大数据之Python进阶(六)多线程的使用

文章目录 多线程的使用1. 导入线程模块2. 线程类Thread参数说明3. 启动线程4. 多线程完成多任务的代码5. 小结 线程执行带有参数的任务1. 线程执行带有参数的任务的介绍2. args参数的使用3. kwargs参数的使用4. 小结 线程的注意点1. 线程的注意点介绍2. 线程之间执行是无序的3.…

5.编写程序 超强力方法

5.1 创建战舰游戏 创建一个类似战舰的游戏:攻击网站 有一种棋盘类的战舰游戏,目标是要猜测对方战舰的坐标,然后轮流开炮攻击,命中数发就可以打沉对方的战舰。不过我们不喜欢战争,只要打垮这些达康公司就好(因为与商业…

10.10为什么要用二进制

由选择器引发的疑问与思考 ?想的是就让每位表示得越多,不就越能节省空间开销,从而不需要那么多的位数? 状态总量为S,R进制的N位数有SR*N, 表示当前这个位数的进制数所能表示最多的状态总量 客观存在的数量在不同进制…

springcloud----检索中间件 ElasticSearch 分布式场景的运用

如果对es的基础知识有不了解的可以看 es看这个文章就会使用了 1.分布式集群场景下的使用 单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。 海量数据存储问题:将索引库从逻辑上拆分为N个分片&#xff08…

【opencv】windows10下opencv4.8.0-cuda版本源码编译教程

【opencv】windows10下opencv4.8.0-cuda版本源码编译教程 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【opencv】windows10下opencv4.8.0-cuda版本源码编译教程前言准备工具cuda/cudnncmakeopencv4.5.0opencv_contrib CMake编译VS2019编译可…

Hadoop2.0探讨

文章目录 8. Hadoop 再探讨8.1 Hadoop的优化与发展8.2 HDFS 的FA和Federation(Hadoop2.0新特性)8.2.1 HDFS HA8.2.2 HDFS Federation 8.3 YARN8.3.1 MapReduce1.0的缺陷8.3.2 Yarn设计思路8.3.3 Yarn体系结构8.3.4 Yarn工作流程8.3.5 Yarn框架和MapReduce1.0框架对比分析8.3.6 …

C# Onnx GFPGAN GPEN-BFR 人像修复

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms;namespace 图像修复 {public partial class Form1 : For…

MAX17058_MAX17059 STM32 iic 驱动设计

本文采用资源下载链接,含完整工程代码 MAX17058-MAX17059STM32iic驱动设计内含有代码、详细设计过程文档,实际项目中使用代码,稳定可靠资源-CSDN文库 简介 MAX17058/MAX17059 IC是微小的锂离子(Li )在手持和便携式设备的电池电量计。MAX170…

MTK8183/MT8183安卓4G核心板_联发科安卓手机开发板主板方案定制

MediaTek MT8183 整合先进功能和 AI 的主流 Chromebook 平台 MTK8183又称为MediaTek Kompanio 500,是一款支持强大功能的Chromebook平台,结合多种高功能硬件于单一高效能芯片。支持连接选项包括 Wi-Fi、蓝芽和 GNSS,外围设备可选择连接 USB …

Flutter 直接调用so动态库,或调用C/C++源文件内函数

开发环境 MacBook Pro Apple M2 Pro | macOS Sonoma 14.0 Android Studio Giraffe | 2022.3.1 Patch 1 XCode Version 15.0 Flutter 3.13.2 • channel stable Tools • Dart 3.1.0 • DevTools 2.25.0 先说下历程,因为我已经使用了Flutter3的版本,起初…

【考研408真题】2022年408数据结构41题---判断当前顺序存储结构树是否是二叉搜索树

文章目录 思路408考研各数据结构C/C代码(Continually updating) 思路 很明显,这是一个顺序存储结构的树的构成方法。其中树的根节点位置从索引0开始,对于该结构,存在有:如果当前根节点的下标为n&#xff0c…

波奇学C++:哈希

哈希本质是的值和位置建立关联起来,这种关联关系就是哈希函数 示例:除留余数:对输入的数字取模。 哈希冲突:多个不同的值指向同一个位置 解决方法: 闭散列:开发地址法。 把24放在下一个位置 哈希桶 闭散列法 闭散列…

NNDL:作业3

在Softmax回归的风险函数(公式(3.39))中如果加上正则化项会有什么影响? (1) 在 Softmax 回归的风险函数中加入正则化项会对模型的训练产生影响。正则化项的作用是对模型的复杂度进行惩罚,防止过拟合的发生。 (2) 原书公式为: 在加入正则化后损失函数…

STM32单片机入门学习(六)-光敏传感器控制LED

光敏传感器模块和LED接线 LED负极接B12,正极接VCC 光敏传感模块一DO端接B13,GND接GND,VCC接VCC,AO不接。 如图: 主程序代码:main.c #include "stm32f10x.h" #include "Delay.h" //delay函数所在头文件 #include …

Python中套接字实现服务端和客户端3-3

3 创建客户端的步骤 创建客户端的步骤如图5所示。 图5 创建客户端的步骤 从图5可以看出,对于客户端来说,首先创建套接字,之后通过创建的套接字去连接服务端,如果连接成功,则继续通过该套接字向服务端发送数据&#x…

扩展windows 10 文件夹文件路径位数

Enable Long Paths in Windows 10, Version 1607, and Later PowerShell Copy New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force 管理员权限运行 PowerShell…

【开源电商网站】(2),使用docker-compose和dockerfile进行配置,设置自定义的镜像,安装插件,增加汉化包,支持中文界面汉化。

项目相关代代码地址 相关内容: https://blog.csdn.net/freewebsys/category_12461196.html 原文地址: https://blog.csdn.net/freewebsys/article/details/133666433 包括以下运行的详细代码: https://gitee.com/study-demo-all/oscommerc…

将cpu版本的pytorch换成gpu版本

1.首先激活虚拟环境 winRcmd 打开dos命令窗口 查看虚拟环境列表 conda env list 激活虚拟环境 2.将原来的pytorch_cpu版本换成gpu版本 注意:安装gpu版本的pytorch时并不需要先卸载原来的cpu版本pytorch,安装时会自己替换的 打开pytorch官网查看以前版本 Previo…

vant组件安装之后导入所有组件报错

问题:引入vant报错(Module build failed (from ./node_modules/postcss-loader/src/index.js): 解决办法:在node_modules里面找到 vant目录下面的lib里面的 index.css; 在url前面加上空格即可