【密码学实战】Java 实现 SM2 国密算法(签名带id、验签及 C1C3C2 加密解密)
前言
SM2是中国国家密码管理局发布的椭圆曲线公钥密码算法标准(GB/T 32918),属于国密算法体系。与RSA和ECDSA相比,SM2在相同安全强度下密钥更短、计算效率更高。本文将介绍如何在Java中实现SM2的密钥生成、数字签名、验签、加密及解密功能。
一、结果验证
1.代码运行结果
1.1 不带id签名验签代码运行结果
1.2 带id签名验签代码运行结果
1.3 SM2加密解密代码运行结果
2.工具验证结果
2.1 不带id签名验签工具运行结果
2.2 带id签名验签工具运行结果
2.3 SM2加密解密工具运行结果
二、SM2签名原理
SM2签名过程的核心是利用私钥对消息进行签名,生成签名值 (r, s)
。具体步骤如下:
-
计算消息的哈希值
使用SM3哈希算法对消息M
进行哈希处理,得到哈希值e
。 -
生成随机数
选择一个随机数k
,满足1 < k < n
,其中n
是椭圆曲线的阶。 -
计算椭圆曲线点
使用随机数k
计算椭圆曲线上的点Q = kG
,其中G
是椭圆曲线的基点。取点Q
的x
坐标x1
。 -
计算签名值
r
计算r = (e + x1) mod n
。如果r = 0
或r + k = n
,则重新选择随机数k
。 -
计算签名值
s
计算s = (1 + d)^{-1} * (k - r * d) mod n
,其中d
是私钥。 -
输出签名结果
签名结果为(r, s)
,通常以字节数组的形式存储和传输。
三、SM2验签原理
SM2验签过程的核心是利用公钥验证签名的有效性。具体步骤如下:
-
计算消息的哈希值
使用SM3哈希算法对消息M
进行哈希处理,得到哈希值e
。 -
计算值
t
计算t = (r + s) mod n
,其中r
和s
是签名值。 -
计算椭圆曲线点
计算点R = sG + tP
,其中G
是椭圆曲线的基点,P
是签名者的公钥。取点R
的x
坐标x1
。 -
验证签名
验证等式r = (e + x1) mod n
是否成立。如果成立,则签名有效;否则,签名无效。
四、SM2签名与验签的Java实现
1. 添加依赖
在pom.xml
中添加Bouncy Castle依赖:
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version>
</dependency>
2. 生成密钥对
/*** 生成SM2密钥对。** @return 生成的密钥对(包含公钥和私钥)* @throws Exception 如果密钥生成过程中发生错误*/public static KeyPair generateKeyPair() throws Exception {// 添加Bouncy Castle安全提供者Security.addProvider(new BouncyCastleProvider());// 获取SM2椭圆曲线参数(使用sm2p256v1曲线)ECParameterSpec sm2Spec = ECNamedCurveTable.getParameterSpec("sm2p256v1");// 创建EC密钥对生成器实例KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");// 初始化密钥对生成器,指定椭圆曲线参数和随机数生成器kpg.initialize(sm2Spec, new SecureRandom());// 生成密钥对并返回return kpg.generateKeyPair();}
3. 签名不带ID
/*** 使用SM2算法进行签名(不使用用户ID)。** @param data 待签名的数据(字节数组)* @param privateKey 签名使用的私钥* @return 签名结果(字节数组)* @throws Exception 如果签名过程中发生错误*/public static String signNoId(byte[] data, PrivateKey privateKey) throws Exception {// 创建SM2签名实例,指定使用SM3哈希算法Signature signature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);// 初始化签名器,使用私钥signature.initSign(privateKey);// 更新待签名的数据signature.update(data);// 生成签名byte[] signatureBytes = signature.sign();// 解析 DER 编码的签名结果ASN1Sequence sequence = ASN1Sequence.getInstance(signatureBytes);BigInteger r = ASN1Integer.getInstance(sequence.getObjectAt(0)).getValue();BigInteger s = ASN1Integer.getInstance(sequence.getObjectAt(1)).getValue();// 打印 r 和 s 的值System.out.println("r 的十六进制值: " + r.toString(16));System.out.println("s 的十六进制值: " + s.toString(16));// 将 r 和 s 拼接为 64 字节的签名结果byte[] rBytes = to32Bytes(r);byte[] sBytes = to32Bytes(s);byte[] rawSignature = new byte[64];System.arraycopy(rBytes, 0, rawSignature, 0, 32);System.arraycopy(sBytes, 0, rawSignature, 32, 32);// 生成签名并返回return Hex.toHexString(rawSignature);}
4. 验签不带ID
/*** 验证SM2签名(不使用用户ID)** @param data 待验证的数据(明文)* @param signature 签名数据(字节数组)* @param publicKey 公钥* @return 验签结果(true表示成功,false表示失败)* @throws Exception 如果验签过程中发生错误*/public static boolean verifyNoId(byte[] data, byte[] signature, PublicKey publicKey) throws Exception {// 初始化SM2签名算法(使用SM3哈希算法)Signature verifier = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);// 初始化验证器,使用公钥verifier.initVerify(publicKey);// 更新待验证的数据verifier.update(data);// 将 r 和 s 拼接格式的签名结果转换为 DER 编码格式byte[] derSignature = convertRawSignatureToDER(signature);// 验证签名return verifier.verify(derSignature);}
5. 测试代码
public static void main(String[] args) throws Exception {// 生成密钥对KeyPair keyPair = generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 提取公钥的 x 和 y 坐标String publicKeyX = ((ECPublicKey) publicKey).getQ().getAffineXCoord().toBigInteger().toString(16);String publicKeyY = ((ECPublicKey) publicKey).getQ().getAffineYCoord().toBigInteger().toString(16);// 拼接 x 和 y 坐标String publicKeyXY = publicKeyX + publicKeyY;System.out.println("X: " + publicKeyX);System.out.println("Y: " + publicKeyY);//System.out.println("公钥: " + publicKeyXY);// 打印私钥的十六进制表示BigInteger privateKeyD = ((ECPrivateKey) privateKey).getD();System.out.println("私钥HEX: " + privateKeyD.toString(16));// 待签名数据String data = "12345";String newData = "1234567";byte[] dataBytes = data.getBytes();//System.out.printf("原文: "+data);byte[] newDat = newData.getBytes();//System.out.printf("原文修改: "+newData);// 签名String signature = signNoId(dataBytes, privateKey);System.out.println("签名结果: " + signature);// 验签boolean isValid = verifyNoId(dataBytes, Hex.decode(signature), publicKey);System.out.println("验签值: " + isValid);// 修改原文验签boolean isVa = verifyNoId(newDat, Hex.decode(signature), publicKey);System.out.println("修改原文验签结果: " + isVa);System.out.printf("==========================================================: ");// 签名带idString dataID = "12345";String dataNew = "123456";String userId ="1234567812345678";String signatureId = signWithID(privateKey, publicKey, dataID, userId);System.out.println("带id签名结果: " + signatureId);// 验签带idboolean isValidId = verifyWithID(publicKey, dataID, userId, Hex.decode(signatureId));System.out.println("带id验签值: " + isValidId);// 验签带id原文修改验证boolean isValidIdNew = verifyWithID(publicKey, dataNew, userId, Hex.decode(signatureId));System.out.println("带id验签值原文修改: " + isValidIdNew);}
五 、SM2带ID签名与验签Java实现
SM2签名标准要求计算哈希值时包含用户身份标识(ID),默认ID为空字符串。但在实际应用中(如金融场景),需明确指定用户ID(如身份证号、手机号等)。以下是Java实现方法:
1.算法原理解析
SM2签名算法中,用户ID(即userId
)被用于生成一个关键值 ZA,其目的是将用户身份与密钥绑定,增强安全性。具体步骤如下:
-
ZA值计算
ZA通过哈希函数(SM3)生成,计算公式为:复制
ZA = HASH( ENTLA || ID || a || b || xG || yG || xA || yA )
- ENTLA:用户ID的比特长度(占2字节,如ID长度256比特则值为0x0100)
- ID:用户自定义标识(如身份证号、手机号)
- a, b:椭圆曲线方程参数
- (xG, yG):椭圆曲线基点坐标
- (xA, yA):签名方的公钥坐标
-
签名过程
- 输入:私钥、待签名数据
M
、用户ID - 输出:签名结果
(r, s)
1. 计算 ZA(如上) 2. 计算 e = HASH(ZA || M) 3. 生成随机数k,计算椭圆曲线点(x1, y1) = [k]G 4. 计算 r = (e + x1) mod n 5. 若r=0或r+k=n,则重新生成k 6. 计算 s = ((1 + d)^−1 * (k − r * d)) mod n(d为私钥) 7. 返回(r, s)
- 输入:私钥、待签名数据
-
验签过程
- 输入:公钥、签名
(r, s)
、原始数据M
、用户ID - 输出:验签结果(true/false)
1. 校验r和s是否在[1, n-1]范围内 2. 计算 ZA(与签名方相同ID) 3. 计算 e = HASH(ZA || M) 4. 计算 t = (r + s) mod n 5. 计算椭圆曲线点(x1, y1) = [s]G + [t]P(P为公钥) 6. 验证 R = (e + x1) mod n 是否等于r
- 输入:公钥、签名
2.代码实现
- 带ID的签名
/*** 使用 SM2 算法进行带用户 ID 的签名,并返回 r 和 s 的拼接结果** @param privateKey 私钥* @param publicKey 公钥* @param data 待签名的数据* @param userId 用户 ID(如企业编号、用户身份证等)* @return 签名结果(Hex 编码的字符串,64 字节)* @throws Exception 如果签名过程中发生错误*/public static String signWithID(PrivateKey privateKey, PublicKey publicKey, String data, String userId) throws Exception {// 将私钥转换为 ECPrivateKeyParametersECPrivateKeyParameters ecPrivateKey = convertPrivateKey(privateKey);// 将公钥转换为 ECPublicKeyParametersECPublicKeyParameters ecPublicKey = convertPublicKey(publicKey);// 创建 SM2 签名器SM2Signer signer = new SM2Signer(new SM3Digest());// 初始化签名器,传入私钥和用户 IDsigner.init(true, new ParametersWithID(ecPrivateKey, userId.getBytes(StandardCharsets.UTF_8)));// 更新待签名的数据signer.update(data.getBytes(StandardCharsets.UTF_8), 0, data.length());// 生成签名byte[] signResult = signer.generateSignature();// 解析 DER 编码的签名结果ASN1Sequence sequence = ASN1Sequence.getInstance(signResult);BigInteger r = ASN1Integer.getInstance(sequence.getObjectAt(0)).getValue();BigInteger s = ASN1Integer.getInstance(sequence.getObjectAt(1)).getValue();// 打印 r 和 s 的值System.out.println("r 的十六进制值: " + r.toString(16));System.out.println("s 的十六进制值: " + s.toString(16));// 将 r 和 s 拼接为 64 字节的签名结果byte[] rBytes = to32Bytes(r);byte[] sBytes = to32Bytes(s);byte[] rawSignature = new byte[64];System.arraycopy(rBytes, 0, rawSignature, 0, 32);System.arraycopy(sBytes, 0, rawSignature, 32, 32);// 返回 Hex 编码的签名结果return Hex.toHexString(rawSignature);}
- 带ID的验签
/*** 使用 SM2 算法进行带用户 ID 的验签** @param publicKey 公钥* @param data 待验签的数据* @param userId 用户 ID(必须与签名时一致)* @param signature 签名结果(字节数组,r 和 s 的拼接格式)* @return 验签结果(true 表示验签成功,false 表示验签失败)* @throws Exception 如果验签过程中发生错误*/public static boolean verifyWithID(PublicKey publicKey, String data, String userId, byte[] signature) throws Exception {// 将公钥转换为 ECPublicKeyParametersECPublicKeyParameters ecPublicKey = convertPublicKey(publicKey);// 创建 SM2 验签器SM2Signer verifier = new SM2Signer(new SM3Digest());// 初始化验签器,传入公钥和用户 IDverifier.init(false, new ParametersWithID(ecPublicKey, userId.getBytes(StandardCharsets.UTF_8)));// 更新待验签的数据verifier.update(data.getBytes(StandardCharsets.UTF_8), 0, data.length());// 将 r 和 s 拼接格式的签名结果转换为 DER 编码格式byte[] derSignature = convertRawSignatureToDER(signature);// 验签return verifier.verifySignature(derSignature);}
六、SM2加密与解密Java实现
1.SM2加密原理
-
SM2加密过程主要基于椭圆曲线的数学特性,通过公钥对明文数据进行加密。具体步骤如下:
- 选择椭圆曲线参数
- 使用椭圆曲线参数(如
sm2p256v1
),这些参数包括椭圆曲线方程的系数、基点G
以及基点的阶n
。
- 使用椭圆曲线参数(如
- 生成随机数
k
- 选择一个随机数
k
(1 < k < n
),用于生成椭圆曲线上的一个点R = [k]G
。
- 选择一个随机数
- 计算密文
- 使用公钥
P
(签名方的公钥)和随机点R
,根据SM2的加密公式计算密文。SM2支持两种加密模式:- C1C3C2模式:密文格式为
C1 || C3 || C2
。 - C1C2C3模式:密文格式为
C1 || C2 || C3
。
- C1C3C2模式:密文格式为
- 其中:
C1
是随机点R
的编码。C2
是经过加密的明文数据。C3
是消息的哈希值,用于验证数据完整性。
- 使用公钥
- 输出密文
- 将计算得到的
C1
、C2
和C3
拼接成最终的密文。
- 将计算得到的
- 选择椭圆曲线参数
2.SM2解密原理
解密过程是加密的逆操作,使用私钥对密文进行解密,还原出原始明文。具体步骤如下:
- 解析密文
- 将密文拆分为
C1
、C2
和C3
。
- 将密文拆分为
- 计算椭圆曲线点
- 使用私钥
d
和C1
中的点R
,根据SM2的解密公式计算椭圆曲线上的一个点。
- 使用私钥
- 还原明文
- 利用椭圆曲线的数学特性,结合
C1
、C2
和C3
,通过解密公式还原出原始明文。
- 利用椭圆曲线的数学特性,结合
- 验证数据完整性
- 使用
C3
验证解密后的数据是否被篡改。
- 使用
3.代码实现
- 添加依赖
在pom.xml
中添加Bouncy Castle依赖:
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version>
</dependency>
- 生成密钥对
/*** 生成SM2密钥对*/public static KeyPair generateSM2KeyPair() throws Exception {// 获取SM2椭圆曲线参数X9ECParameters ecParameters = GMNamedCurves.getByName("sm2p256v1");ECParameterSpec ecSpec = new ECParameterSpec(ecParameters.getCurve(),ecParameters.getG(),ecParameters.getN(),ecParameters.getH());// 创建密钥对生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");keyPairGenerator.initialize(ecSpec, new SecureRandom());return keyPairGenerator.generateKeyPair();}
- 公钥加密
/*** SM2加密(C1C3C2模式)* @param publicKey 公钥* @param data 待加密数据* @return 加密后的字节数组(C1C3C2格式)*/public static byte[] encrypt(BCECPublicKey publicKey, byte[] data) throws Exception {// 获取椭圆曲线参数ECDomainParameters domainParams = new ECDomainParameters(publicKey.getParameters().getCurve(),publicKey.getParameters().getG(),publicKey.getParameters().getN());// 创建加密引擎(默认输出C1C3C2格式)SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C3C2);// 初始化加密引擎ECPublicKeyParameters pubKeyParams = new ECPublicKeyParameters(publicKey.getQ(),domainParams);engine.init(true, new ParametersWithRandom(pubKeyParams, new SecureRandom()));return engine.processBlock(data, 0, data.length);}
- 私钥解密
/*** SM2解密(C1C3C2模式)* @param privateKey 私钥* @param cipherData 密文数据(C1C3C2格式)* @return 解密后的字节数组*/public static byte[] decrypt(BCECPrivateKey privateKey, byte[] cipherData) throws Exception {// 获取椭圆曲线参数ECDomainParameters domainParams = new ECDomainParameters(privateKey.getParameters().getCurve(),privateKey.getParameters().getG(),privateKey.getParameters().getN());// 创建解密引擎(设置为C1C3C2模式)SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C3C2);// 初始化解密引擎ECPrivateKeyParameters priKeyParams = new ECPrivateKeyParameters(privateKey.getD(),domainParams);engine.init(false, priKeyParams);return engine.processBlock(cipherData, 0, cipherData.length);}
注意事项
- 密钥管理:私钥需安全存储(如密码机或云密码机等)
- 性能优化:加解密大数据时建议使用SM4对称加密配合SM2密钥交换
- ID编码:
userId.getBytes()
需与业务方约定编码格式(如UTF-8、HEX等) - 长度限制:ID长度建议不超过65535字节(规范限制)
- 跨系统交互:与其他系统(如C++、Go)对接时需确认ID处理逻辑一致性
总结
希望这篇文章对你有所帮助!如果觉得不错,别忘了关注哦!
相关文章:
【密码学实战】Java 实现 SM2 国密算法(签名带id、验签及 C1C3C2 加密解密)
前言 SM2是中国国家密码管理局发布的椭圆曲线公钥密码算法标准(GB/T 32918),属于国密算法体系。与RSA和ECDSA相比,SM2在相同安全强度下密钥更短、计算效率更高。本文将介绍如何在Java中实现SM2的密钥生成、数字签名、验签、加密及…...
如何修改安全帽/反光衣检测AI边缘计算智能分析网关V4的IP地址?
TSINGSEE青犀推出的智能分析网关V4,是一款集成了BM1684芯片的高性能AI边缘计算智能硬件。其内置的高性能8核ARM A53处理器,主频可高达2.3GHz,INT8峰值算力更是达到了惊人的17.6Tops。此外,该硬件还预装了近40种AI算法模型…...
LLM的演进趋势与未来展望:Toformer的革新之路
文章出处 题目:Restoring Images in Adverse Weather Conditions via Histogram Transformer 论文地址: https://arxiv.org/pdf/2407.10172 代码地址: https://github.com/sunshangquan/Histoformer 年份:2024 期刊:ECCV 背景 这篇文章…...
LabVIEW 无法播放 AVI 视频的编解码器解决方案
用户在 LabVIEW 中使用示例程序 Read AVI File.vi(路径: 📌 C:\Program Files (x86)\National Instruments\LabVIEW 2019\examples\Vision\Files\Read AVI File.vi)时发现: ✅ LabVIEW 自带的 AVI 视频可正常播放 这是…...
Svelte vs Vue:前端框架的深度对比与应用场景分析
Svelte vs Vue:前端框架的深度对比与应用场景分析 1. 引言 前端开发领域的框架选择一直是开发者关注的重点。在现代 Web 开发中,Vue 和 Svelte 都是备受瞩目的框架,各自拥有不同的架构设计和适用场景。本文将从 核心架构、性能对比、开发体…...
如何在一台服务器上搭建 mongodb副本集1主2从节点
在一台服务器上搭建 MongoDB 副本集(1 主节点 2 从节点)可以通过运行多个 MongoDB 实例并使用不同端口和数据目录来实现。以下是详细步骤: 1. 准备工作 确保已安装 MongoDB。为每个实例创建独立的数据目录和日志文件。 2. 创建数据目录和…...
【湖北省计算机信息系统集成协会主办,多高校支持 | ACM出版,EI检索,往届已见刊检索】第二届边缘计算与并行、分布式计算国际学术会议(ECPDC 2025)
第二届边缘计算与并行、分布式计算国际学术会议(ECPDC 2025)将于2025年4月11日至13日在中国武汉盛大召开。本次会议旨在为边缘计算、并行计算及分布式计算领域的研究人员、学者和行业专家提供一个高水平的学术交流平台。 随着物联网、云计算和大数据技术…...
谈谈 ES 6.8 到 7.10 的功能变迁(6)- 其他
这是 ES 7.10 相较于 ES 6.8 新增内容的最后一篇,主要涉及算分方法和同义词加载的部分。 自定义算分:script_score 2.0 Elasticsearch 7.0 引入了新一代的函数分数功能,称为 script_score 查询。这一新功能提供了一种更简单、更灵活的方式来…...
大数据与金融科技:革新金融行业的动力引擎
大数据与金融科技:革新金融行业的动力引擎 在今天的金融行业,大数据与金融科技的结合正在以惊人的速度推动着金融服务的创新与变革。通过精准的数据分析与智能化决策,金融机构能够更高效地进行风险管理、客户服务、资产管理等一系列关键操作…...
企业jsapi_ticket,java举例
在企业微信开发中,使用 Java 获取 jsapi_ticket 并生成签名的步骤如下。以下是完整的 Java 示例代码。 1. 获取 jsapi_ticket 的流程 获取 access_token。 使用 access_token 获取 jsapi_ticket。 使用 jsapi_ticket 生成签名(signature)。…...
【Python】基础语法三
> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:了解Python的函数、列表和数组。 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! > 专栏选自ÿ…...
leetcode_字典树 139. 单词拆分
139. 单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 思路: 定义状态: 设dp[i]表…...
Easy Trans Spring Boot Starter ---Spring系列的字段翻译库
Easy Trans Spring Boot Starter 使用文档 1. 简介 easy-trans-spring-boot-starter 是一个基于 Spring Boot 的库,用于简化数据翻译和转换操作。它可以帮助你将数据库中的枚举值、状态码等转换为用户友好的文本,或者将一种数据格式转换为另一种格式。…...
算法-数据结构(图)-迪杰斯特拉最短逻辑算法( Dijkstra)
迪杰斯特拉算法(Dijkstras Algorithm) 是一种用于计算单源最短路径的经典算法,由荷兰计算机科学家 艾兹赫尔迪杰斯特拉(Edsger W. Dijkstra) 于1956年提出。它的主要目标是找到从图中的某个源节点到所有其他节点的最短…...
抖音生活服务加强探店内容治理,2024年达人违规率下降30%
发布 | 大力财经 2月27日,抖音生活服务发布《2024抖音生活服务消费者权益保护年度报告》(以下简称“报告”)。报告显示,过去一年,抖音生活服务针对消费者反感的虚假、夸张探店内容,开展了专项治理。通过一…...
跟着源码实现LevelDB(二)util/status.cc
概述 本小节实现了leveld的Status类,Status看起来是个简单的类,但是其中也包含了leveldb对极致的性能实现的巧妙设计 Status的内存管理 Status 只有一个成员变量 const char* state_; state[0…3] 表示长度,state[4] 1个字节 表示状态的枚…...
51c自动驾驶~合集52
我自己的原文哦~ https://blog.51cto.com/whaosoft/13383340 #世界模型如何推演未来的千万种可能 驾驶世界模型(DWM),专注于预测驾驶过程中的场景演变,已经成为追求自动驾驶的一种有前景的范式。这些方法使自动驾驶系统能够更…...
Rust 是什么
Rust 是什么 Rust 是一种由 Mozilla 开发的系统级编程语言,它于 2010 年首次亮相,在 2015 年发布 1.0 版本,此后迅速发展并受到广泛关注。 内存安全:Rust 最大的亮点之一是它在编译阶段就能够避免常见的内存错误,如空指针引用、数据竞争和内存泄漏等。它通过所有权(Owne…...
005 公网访问 docker rocketmq
文章目录 创建自定义网络创建NameServer容器创建Broker容器正式开始启动 Nameserver 容器启动 Broker 容器并关联 Nameserverdocker exec -it rmqbroker vi /etc/rocketmq/broker.conf检查 namesrv 解析检查 Broker 注册状态Nameserver 日志Broker 日志检查容器日志手动指定 Br…...
ASP.NET MVC项目部署到IIS后,w3wp.exe程序报错重启
一、错误信息 windows的事件查看器》windows日志》应用程序,按时间找到错误信息如下: 错误应用程序名称: w3wp.exe,版本: 10.0.14393.0,时间戳: 0x57899b8a 错误模块名称: KERNELBASE.dll,版本: 10.0.14393.5850&…...
Java多线程与高并发专题——深入ReentrantReadWriteLock
深入ReentrantReadWriteLock 读写锁出现原因 synchronized和ReentrantLock都是互斥锁。如果说有一个操作是读多写少的,还要保证线程安全的话。如果采用上述的两种互斥锁,效率方面很定是很低的。在这种情况下,咱们就可以使用ReentrantReadWr…...
支付宝 IoT 设备入门宝典(下)设备经营篇
上篇介绍了支付宝 IoT 设备管理,但除了这些基础功能外,商户还可以利用设备进行一些运营动作,让设备更好的帮助自己,本篇就会以设备经营为中心,介绍常见的设备相关能力和问题解决方案。如果对上篇感兴趣,可以…...
极简本地体验deepseek大模型教程
一 题外随感:时代之问 就像狄更斯在双城记中所述,“这是最好的时代,这是最坏的时代”。每一代人都有其所处的时代,每一个时代都有其所谓好的一面和不那么好的一面。很多时候随口的一句大环境不好,就似乎给了自己一个最…...
最短路问题--Floyd
Floyd算法 一、介绍二、补充知识:邻接矩阵三、原理四、实现 提示:以下是本篇文章正文内容,下面案例可供参考 一、介绍 Floyd算法是一种用来计算图中所有点之间最短距离的算法。它的核心思想是:通过逐步尝试每个点作为中间点&…...
深入理解Java网络编程:从基础到高级应用
一、网络编程概述 1.什么是网络编程? 网络编程是指利用计算机网络实现程序之间通信的一种编程方式。在网络编程中,程序需要通过网络协议(如 TCP/IP)来进行通信,以实现不同计算机之间的数据传输和共享。 2.在网络编程…...
浅谈deepseek环境搭建
在探索人工智能的浩瀚宇宙中,DeepSeek如同一颗璀璨的星辰,以其独特的魅力引领着我们在逻辑推理与数据分析的海洋中遨游。想要在这片未知的领域里扬帆起航,首先必须精心搭建起我们的“星际飞船”——DeepSeek环境。无论你是渴望在本地实例上运…...
AI绘画软件Stable Diffusion详解教程(2):Windows系统本地化部署操作方法(专业版)
一、事前准备 1、一台配置不错的电脑,英伟达显卡,20系列起步,建议显存6G起步,安装win10或以上版本,我的显卡是40系列,16G显存,所以跑大部分的模型都比较快; 2、科学上网࿰…...
kali liux的下载
Kali Linux | Penetration Testing and Ethical Hacking Linux Distributionhttps://www.kali.org/ VMware虚拟机https://pan.quark.cn/s/aa869ffbf184 【补充一个今天学到的知识昂和内容无关:(遥感)指非接触的远距离探测技术,使用传感器探…...
DeepSeek 助力 Vue3 开发:打造丝滑的悬浮按钮(Floating Action Button)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
ES from size聚合查询10000聚合查询,是每个分片先聚合,再统计。还是所有节点查询1万条后,再聚合
在 Elasticsearch 中,聚合查询 的执行过程是 分布式 的,Elasticsearch 会先在每个分片(shard)上执行本地聚合,然后再在协调节点(coordinating node)上对所有分片的聚合结果进行 全局汇总。具体过…...
fluent-ffmpeg 依赖详解
fluent-ffmpeg 是一个用于在 Node.js 环境中与 FFmpeg 进行交互的强大库,它提供了流畅的 API 来执行各种音视频处理任务,如转码、剪辑、合并等。 一、安装 npm install fluent-ffmpeg二、基本使用 要使用 fluent-ffmpeg,首先需要确保系统中…...
SLAM文献之-DROID-SLAM: Deep Visual SLAM for Monocular, Stereo, and RGB-D Cameras
DROID-SLAM 是一种结合深度学习与传统视觉SLAM技术的先进算法,其核心目标是通过端到端可训练的深度神经网络来实现高精度的相机位姿估计和稠密三维重建。与传统SLAM方法不同,DROID-SLAM采用深度学习网络来估计深度信息,提供更高的精度与鲁棒性…...
一、旋转编码器模块分析与使用
一、旋转编码器说明 该模块配合定时器的encoder使用时,可通过旋转来进行调整记录编码的数值。(通过旋转编码器的数值与字母建立对应关系,即可进行打字编码) 引脚说明: vcc,gnd,供电使用 sw&am…...
【踩坑日志】解决CU118环境下RuntimeError: NCCL error: invalid usage
本博客主要记录了CU118环境下,出现报错信息为RuntimeError: NCCL error: invalid usage的解决方案。我的环境信息如下: cuda版本:11.7torch版本:torch-2.5.1-cu118 定位到核心报错信息为: NCCL WARN NCCL cannot be …...
FREERTOS的三种调度方式
一、调度器的调度方式 调度器的调度方式解释针对的对象抢占式调度1.高优先级的抢占低优先级的任务 2.高优先级的任务不停止,低优先级的任务不能执行 3.被强占的任务会进入就绪态优先级不同的任务时间片调度1.同等优先级任务轮流享用CPU时间 2.没有用完的时间片&…...
338.比特位计数<动态规划>
338. 比特位计数 - 力扣(LeetCode) class Solution { public:vector<int> countBits(int n) {//将所有数初始化为0vector<int>dp(n1,0);for(int i 0; i<n;i){if(i % 2 0){dp[i] dp[i/2];}else{dp[i] dp[i/2]1;}}return dp;} };...
释放你的IDE潜能:Code::Blocks 插件创意开发深度指南
释放你的IDE潜能:Code::Blocks 插件创意开发深度指南 在软件开发的浩瀚世界中,集成开发环境 (IDE) 扮演着至关重要的角色。一款优秀的 IDE 不仅能提升开发效率,更能激发开发者的创造力。Code::Blocks,作为一款开源、跨平台的 C, C++ 和 Fortran IDE,以其轻量级、高度可定…...
行星际激波与高能粒子的相互作用机制及其天体物理意义
第一章 行星际激波的物理本质与形成机制 1.1 激波的普遍定义与分类 激波(Shock Wave)是介质中传播的压缩性不连续面,其本质是介质参数(如密度、速度、压力)的突变。在天体物理中,根据激波传播方向与磁场…...
C# 牵手DeepSeek:打造本地AI超能力
一、引言 在人工智能飞速发展的当下,大语言模型如 DeepSeek 正掀起新一轮的技术变革浪潮,为自然语言处理领域带来了诸多创新应用。随着数据隐私和安全意识的提升,以及对模型部署灵活性的追求,本地部署 DeepSeek 成为众多开发者和…...
不同版本的BLE和WiFi有什么区别?
一、蓝牙技术对比:从 Bluetooth 4.0 到 5.3 的演进与室内定位应用 蓝牙技术自推出以来,经历了多次重大升级,每一代都在传输速率、功耗、覆盖范围和功能上有所改进。本文将从 Bluetooth 4.0 到 5.3,逐一对比各版本的特点࿰…...
LVS+Keepalived高可用高性能负载实战
高可用集群( High Availability Cluster, HA 集群),其中高可用的含义是最大限度地可以使用。从集群 的名字上可以看出,此类集群实现的功能是保障用户的应用程序持久、不间断地提供服务。 当应用程序出现故障或者系统硬件、网络出现…...
网络安全-使用DeepSeek来获取sqlmap的攻击payload
文章目录 概述DeepSeek使用创建示例数据库创建API测试sqlmap部分日志参考 概述 今天来使用DeepSeek做安全测试,看看在有思路的情况下实现的快不快。 DeepSeek使用 我有一个思路,想要测试sqlmap工具如何dump数据库的: 连接mysql数据库&#…...
【MongoDB】在Windows11下安装与使用
官网下载链接:Download MongoDB Community Server 官方参考文档:https://www.mongodb.com/zh-cn/docs/manual/tutorial/install-mongodb-on-windows/#std-label-install-mdb-community-windows 选择custom类型,其他默认 注意,此选…...
vscode输入!+tab没反应??
!+tab直接生成html框架 第一步 ctrlshipp 选择更改语言模式 change language mode, 选择HTML 然后试一下行不行,如果还不行看第二步 第二步 检查一下输入的!是不是英文输入法输入的,一定要是英文输入&…...
【Cadence射频仿真学习笔记】2.4GHz低噪放LNA仿真设计
课程分为3个部分, 一、LNA结构与噪声优化方法 噪声优化的方法是:限定功耗的噪声和功率同时匹配噪声匹配和功率匹配一般不会同时达到, 对于PCSNIM结构的噪声分析,我们只需要了解与哪些参数有关优化思路是:1.信号源阻抗…...
初阶MySQL(两万字全面解析)
文章目录 1.初识MySQL1.1数据库1.2查看数据库1.3创建数据库1.4字符集编码和排序规则1.5修改数据库1.6删除数据库 2.MySQL常用数据类型和表的操作2.(一)常用数据类型1.数值类2.字符串类型3.二进制类型4.日期类型 2.(二)表的操作1查看指定库中所有表2.创建表 3.查看表结构和查看表…...
Python每日一练:学习指南进行汇总
Python,一种“优雅”、“明确”、“简单”的编程语言,凭借其低学习曲线、强大的开源生态系统、卓越的平台可移植性以及面向对象和函数式编程的支持,成为了众多开发者首选。 01 Python 应用领域和就业形势分析 Python,一种“优雅…...
Spring-AI搭建企业专属知识库 一
环境介绍:Spring3.3.2 JDK 21 POM文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&…...
Python的那些事第三十六篇:基于 Vega 和 Vega-Lite 的数据可视化解决方案,Altair 声明式可视化库
Altair 声明式可视化库:基于 Vega 和 Vega-Lite 的数据可视化解决方案 摘要 在数据科学和分析领域,有效的数据可视化是理解数据、发现模式和传达见解的关键。Python 作为数据科学的主要编程语言之一,提供了多种数据可视化库。其中,Altair 是一个基于 Vega 和 Vega-Lite 的…...
虚拟化园区网络部署指南
《虚拟化园区网络部署指南》属于博主的“园区网”专栏,若想成为HCIE,对于园区网相关的知识需要非常了解,更多关于园区网的内容博主会更新在“园区网”专栏里,请持续关注! 一.前言 华为CloudCampus解决方案基于智简网络…...