Java实现加密(七)国密SM2算法的签名和验签(附商用密码检测相关国家标准/国密标准下载)
目录
- 一、国密标准中,关于SM2签名验签的定义
- 二、SM2签名和验签的实现原理
- 1. 前置知识
- 2. 签名生成过程
- 3. 验签过程
- 4. 数学正确性证明
- 5. 安全性与注意事项
- 三、带userId、不带userId的区别
- 1. 核心区别
- 2.算法区别
- (1) 哈希计算过程
- (2) 签名验签流程
- 四、Java代码实现
- 1. Maven 依赖
- 2. 代码实现
- 3. 测试结果
- 4. 签名结果解析R和S
- 5. 在线验证
- 五、签名的ASN.1结构解析
- 1. ASN.1整体结构
- 2. 字段解析
- 3. 关键字段说明
- 4. 为什么需要 `00` 前缀?
- 5. 实际签名示例
- 6. 代码验证(Java + Bouncy Castle)
- 五、补充:商用密码检测相关标准下载
- 1. GB/T 15843 国家标准(权限鉴别相关)
- 2. GB/T 38540国家标准(电子 签章相关,参考)
- 3. GM/T 0003 国密标准(SM2算法)
- 4. GM/T 0031国密标准(电子签章相关,参考)
- 5.其余国家标准下载
- 6. 其余国密标准下载
- 7. GB/T 38540 国家标准和 GM/T 0031 国密标准的应用场景差异:

一、国密标准中,关于SM2签名验签的定义
参考 《GM∕T 0003-2010 SM2椭圆曲线公钥密码算法.pdf》
其中第2部分对于数字签名的描述如下:
数字签名算法
由一个 签名者 对数据产生数字签名,并由一个 验证者 验证签名的可靠性。每个签名都有一个公钥和私钥,其中私钥用于产生签名,验证者用签名者的公钥验证签名。
标准原始描述截图如下:
补充:《SM2椭圆曲线公钥密码算法》共分为四个部分:
- 第1部分:总则
- 第2部分:数字签名算法
- 第3部分:密钥交换协议
- 第4部分:公钥加密算法
注意:在 SM2 算法中涉及的公钥、私钥、签名的长度基本是固定的,以下为标准长度,可以比对参考长度是否争取:
标准公钥:
23BCB208E10056523D4F4090C0130D5B8898A858E8D5D9FF3B16572FA04E70E28A88459060FF5D88CC53D77407619F9B8B584317A30EDDFCA71DC4965F3ED143
标准私钥:
CBD981B9C2FC49D9E497A68EB4EA3AC2E33472CCECBA7EA803B1A1DDB3B0EBCE
标准签名数据:
R:D00C1DEFEAD263A0FEDDE0AEC26274DBB80719385BB3DDD9AB2A31FB11F378C3
R:00CE562BE2CEB0DDD0DD18E925FF00AB87BB67BB33F4234967F82EDC3798265CDF
S:F1BEDD87A2B17D7150E4ECDCFAEB0D3E34AFE5985CB4EFA39D4FDCE7B32CFBE4
在线网址:
SM2 密钥在线生成工具:https://const.net.cn/tool/sm2/genkey/
SM2 在线签名生成工具(带userId):https://const.net.cn/tool/sm2/sign/
SM2 在线验签工具(带userId):https://const.net.cn/tool/sm2/verify/
二、SM2签名和验签的实现原理
1. 前置知识
- 椭圆曲线参数:
SM2 使用特定的椭圆曲线方程(如 y^2 = x^3 + ax + b )和公开参数:- 基点 G(生成元)。
- 阶 n(基点的阶,一个大素数)。
- 密钥对:
- 私钥 d:随机数,1 ≤ d ≤ n−1。
- 公钥 P:椭圆曲线上的点,P = d ⋅ G。
- 哈希函数:
SM3 算法(国密标准哈希函数),用于计算消息和用户ID的哈希值。
2. 签名生成过程
签名者对消息 M 生成签名 (r,s),步骤如下:
步骤 1:计算哈希值 ZA 和 e
-
用户ID哈希(ZA):
将用户ID(如身份证号、邮箱等)与公钥绑定,防止身份伪造:Z A = SM3 ( UserID ∥ 公钥坐标 ∥ 曲线参数 ) ZA = \text{SM3}(\text{UserID} \parallel \text{公钥坐标} \parallel \text{曲线参数}) ZA=SM3(UserID∥公钥坐标∥曲线参数)
-
消息哈希(e):
结合 ZA 和原始消息 M:e = SM3 ( Z A ∥ M ) e = \text{SM3}(ZA \parallel M) e=SM3(ZA∥M)
步骤 2:生成随机数 k
- 随机选择 k∈[1,n−1],且每次签名必须不同(否则私钥会泄露)。
步骤 3:计算临时椭圆曲线点 (x1, y1)
( x 1 , y 1 ) = k ⋅ G (x₁, y₁) = k \cdot G (x1,y1)=k⋅G
-
取 x1 的整数形式,计算 r :
r = ( e + x 1 ) m o d n r = (e + x₁) \mod n r=(e+x1)modn
若 r=0 或 r+k=n,需重新选择 k。
**步骤 4:计算签名值 s
s = ( 1 + d ) − 1 ⋅ ( k − r ⋅ d ) m o d n s = (1 + d)^{-1} \cdot (k - r \cdot d) \mod n s=(1+d)−1⋅(k−r⋅d)modn
- (1+d)−1 是模 n 下的乘法逆元。
- 若 s=0,需重新签名。
最终签名
输出 (r,s) 作为数字签名(通常编码为 64 字节,r 和 s 各 32 字节)。
3. 验签过程
验签者使用公钥 P 验证签名 (r, s) 的合法性:
步骤 1:检查 r 和 s 范围
- 确保 r, s∈[1, n−1],否则验签失败。
步骤 2:重新计算哈希值 e
- 使用相同的 UserID 和公钥计算 ZA 和 e(与签名过程一致)。
步骤 3:计算中间值 t
t = ( r + s ) m o d n t = (r + s) \mod n t=(r+s)modn
- 若 t=0,验签失败。
步骤 4:恢复临时点 (x1, y1)
( x 1 , y 1 ) = s ⋅ G + t ⋅ P (x₁, y₁) = s \cdot G + t \cdot P (x1,y1)=s⋅G+t⋅P
-
利用公钥 P=d⋅G,推导如下:
s ⋅ G + t ⋅ P = s ⋅ G + t ⋅ d ⋅ P = ( s + t ⋅ d ) ⋅ G s \cdot G + t \cdot P = s \cdot G + t \cdot d \cdot P = (s + t \cdot d) \cdot G s⋅G+t⋅P=s⋅G+t⋅d⋅P=(s+t⋅d)⋅G
-
签名时:
s ≡ ( 1 + d ) − 1 ⋅ ( k − r d ) m o d n s ≡ (1+d)^{−1} \cdot (k−rd) \mod n s≡(1+d)−1⋅(k−rd)modn
,代入可得:
s + t ⋅ d ≡ k m o d n s + t \cdot d ≡ k \mod n s+t⋅d≡kmodn
-
因此恢复的点应为 k ⋅ G,即签名时的 (x1, y1)。
-
步骤 5:验证 r 的合法性
R = ( e + x 1 ) m o d n R = (e + x₁) \mod n R=(e+x1)modn
- 检查是否满足 R = r :
- 若成立,验签通过;否则失败。
4. 数学正确性证明
验签的关键在于通过公钥 P 和签名 (r, s) 重构出签名时的临时点 k⋅G :
-
签名时:
s ≡ ( 1 + d ) − 1 ( k − r d ) m o d n s \equiv (1 + d)^{-1}(k - r d) \mod n s≡(1+d)−1(k−rd)modn
-
两边乘 (1+d) 得:
s ( 1 + d ) ≡ k − r d m o d n s(1+d) \equiv k - rd \mod n s(1+d)≡k−rdmodn
-
整理后:
k ≡ s + ( s + r ) d m o d n k \equiv s + (s + r)d \mod n k≡s+(s+r)dmodn
- 注意到 t = r + s,故 k ≡ s + td mod n。
-
验签时计算的点:
s ⋅ G + t ⋅ P = ( s + t d ) ⋅ G = k ⋅ G s \cdot G + t \cdot P = (s + td) \cdot G = k \cdot G s⋅G+t⋅P=(s+td)⋅G=k⋅G
- 与签名时的 (x1, y1) 一致,确保 x₁ 匹配。
5. 安全性与注意事项
- 随机数 k 的安全性:
- k 必须不可预测且不重复,否则攻击者可通过两次签名反推私钥(类似 ECDSA 的漏洞)。
- UserID 的作用:
- 绑定用户身份与公钥,防止公钥替换攻击。
- 哈希函数:
- 必须使用 SM3 算法,确保与国密标准兼容。
- 抵抗攻击:
- 基于椭圆曲线离散对数问题(ECDLP)的困难性,无法从 P=d⋅G 推导出 d。
三、带userId、不带userId的区别
SM2的签名验签分为带userId和不带userId两种,主要是根据签名验签时是否需要userId作为入参来进行区分。
- 带 UserID:
多一步预处理(计算ZA
),将用户身份、公钥和曲线参数绑定到哈希中,形成身份感知的签名。 - 不带 UserID:
跳过预处理,仅哈希原始消息,签名仅依赖公钥和消息本身。
1. 核心区别
特性 | 带 UserID 的 SM2 | 不带 UserID 的 SM2 |
---|---|---|
哈希输入 | 计算 `ZA = SM3(UserID | |
身份绑定 | 签名与特定用户身份(UserID)强绑定 | 仅绑定公钥和消息,无用户身份信息 |
安全性 | 防止公钥替换攻击(需伪造 UserID) | 仅依赖公钥,易受公钥替换攻击 |
国密标准合规性 | ✅符合 GM/T 0003-2012 标准 | ❌非标准用法,通常不推荐 |
2.算法区别
(1) 哈希计算过程
-
带 UserID:
-
先计算
ZA
(用户身份哈希):Z A = SM3 ( UserID ∥ 公钥坐标 ∥ 曲线参数 ) ZA = \text{SM3}(\text{UserID} \parallel \text{公钥坐标} \parallel \text{曲线参数}) ZA=SM3(UserID∥公钥坐标∥曲线参数)
-
再计算消息哈希
e
:e = SM3 ( Z A ∥ M ) e = \text{SM3}(ZA \parallel M) e=SM3(ZA∥M)
- 作用:将用户身份、公钥和消息绑定,确保签名无法被其他用户复用。
-
-
不带 UserID:
直接计算消息哈希:e = SM3 ( Z A ∥ M ) e = \text{SM3}(ZA \parallel M) e=SM3(ZA∥M)
- 风险:攻击者可替换公钥,伪造签名(缺乏身份绑定)。
(2) 签名验签流程
-
带 UserID:
-
签名:
r = ( e + x 1 ) m o d n ( x 1 来自 k ⋅ G ) r = (e + x₁) \mod n \space\space\space\space\space (x₁来自 k\cdot G) r=(e+x1)modn (x1来自k⋅G)
s = ( 1 + d ) − 1 ⋅ ( k − r ⋅ d ) m o d n s = (1+d)^{-1} \cdot (k - r \cdot d) \mod n s=(1+d)−1⋅(k−r⋅d)modn
-
验签:
验签方需使用相同的UserID
重新计算ZA
和e
,否则验签失败。
-
-
不带 UserID:
跳过ZA
计算,直接使用e = SM3(M)
,其余步骤相同。
四、Java代码实现
1. Maven 依赖
<!-- BC库 -->
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version>
</dependency>
2. 代码实现
SM2WithUserIdExample.java
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithID;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.util.encoders.Hex;import java.security.*;public class SM2WithUserIdExample {static {Security.addProvider(new BouncyCastleProvider());}// SM2曲线参数private static final ECNamedCurveParameterSpec SM2_SPEC = ECNamedCurveTable.getParameterSpec("sm2p256v1");public static void main(String[] args) throws Exception {// 生成SM2密钥对KeyPair keyPair = generateSM2KeyPair();System.out.println("Public Key: " + Hex.toHexString(keyPair.getPublic().getEncoded()));System.out.println("Private Key: " + Hex.toHexString(keyPair.getPrivate().getEncoded()));// 用户IDbyte[] userId = "1234567812345678".getBytes();// 待签名的消息String message = "Hello, SM2!";// 使用用户ID进行签名byte[] signature = signWithUserId(keyPair.getPrivate(), userId, message.getBytes());System.out.println("Signature: " + Hex.toHexString(signature));// 使用用户ID进行验签boolean isValid = verifyWithUserId(keyPair.getPublic(), userId, message.getBytes(), signature);System.out.println("Signature valid: " + isValid);}// 生成SM2密钥对public static KeyPair generateSM2KeyPair() throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");keyPairGenerator.initialize(SM2_SPEC, new SecureRandom());return keyPairGenerator.generateKeyPair();}// 使用用户ID进行签名public static byte[] signWithUserId(PrivateKey privateKey, byte[] userId, byte[] message) throws Exception {ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(((java.security.interfaces.ECPrivateKey) privateKey).getS(),new ECDomainParameters(SM2_SPEC.getCurve(), SM2_SPEC.getG(), SM2_SPEC.getN()));SM2Signer signer = new SM2Signer();signer.init(true, new ParametersWithID(privKey, userId));signer.update(message, 0, message.length);return signer.generateSignature();}// 使用用户ID进行验签public static boolean verifyWithUserId(PublicKey publicKey, byte[] userId, byte[] message, byte[] signature) throws Exception {java.security.spec.ECPoint publicPoint = ((java.security.interfaces.ECPublicKey) publicKey).getW();org.bouncycastle.math.ec.ECPoint bcPublicPoint = SM2_SPEC.getCurve().createPoint(publicPoint.getAffineX(),publicPoint.getAffineY());ECPublicKeyParameters pubKey = new ECPublicKeyParameters(bcPublicPoint,new ECDomainParameters(SM2_SPEC.getCurve(), SM2_SPEC.getG(), SM2_SPEC.getN()));SM2Signer verifier = new SM2Signer();verifier.init(false, new ParametersWithID(pubKey, userId));verifier.update(message, 0, message.length);return verifier.verifySignature(signature);}
}
3. 测试结果
Public Key: 04d1a1065f36c116040a5aef12c2f9f34fd26a0af4e639f6602f9ad252fdaddcbe62bb4c7e065b6391822ec56e6822baded04bd98cf909a846e4a17b61cc9ae7de
Private Key: 308193020100301306072a8648ce3d020106082a811ccf5501822d047930770201010420c9e443b10c9f567cfa014f2982a307bf5473612540fc597a1bffa4be8f277b9ca00a06082a811ccf5501822da14403420004d1a1065f36c116040a5aef12c2f9f34fd26a0af4e639f6602f9ad252fdaddcbe62bb4c7e065b6391822ec56e6822baded04bd98cf909a846e4a17b61cc9ae7de
Message: 48656c6c6f2c20534d3221
Signature: 3046022100a3a8ed43fd20d85edfc72744eebf58a205b8c92e87dd7c286770f2e9f22aee68022100fcab418b2961cce41f514fe1851d85266cef66cf5178201778b570e8eebb8d9f
Signature valid: true
4. 签名结果解析R和S
签名内容实际是16进制ASN.1格式的字节流,我们可以使用工具网站进行在线解析。
- 解析网站: https://the-x.cn/zh-cn/encodings/Asn1.aspx
解析结果如下:
- R:A3A8ED43FD20D85EDFC72744EEBF58A205B8C92E87DD7C286770F2E9F22AEE68
- S:FCAB418B2961CCE41F514FE1851D85266CEF66CF5178201778B570E8EEBB8D9F
5. 在线验证
- 验证网址: https://const.net.cn/tool/sm2/verify/
我们将对应的公钥、原文、签名(R+S)按照十六进制格式输入之后就可以成功验证了。
注意:
1.公钥信息需要去除04前缀;
2.原文不要直接输入,需要转换为十六进制;
3.签名的R、S需要去除00前缀。
如果验证结果为空,页面会展示具体的报错原因,在如下图所示的位置:
(例如公钥没有去除 04
前缀时的报错)
五、签名的ASN.1结构解析
我们将上一步代码生成示例的原签名和解析后的 R、S 进行拆分比对:
可以发现签名的拼接规律如下:
完整签名=3046+022100+R+022100+S
看到这里,恭喜你!你已经发现了ASN.1结构的规律!
1. ASN.1整体结构
SM2 签名默认输出为 DER 编码的 ASN.1 格式,包含两个整数 r
和 s
。完整编码结构如下:
SEQUENCE (30) → 包含两个 INTEGER (02)│├── INTEGER (02) → r└── INTEGER (02) → s
2. 字段解析
以 3046022100...022100...
为例:
字节位置 | 值(Hex) | 含义 |
---|---|---|
0-1 | 30 | SEQUENCE 标签,表示后续是一个结构体。 |
2 | 46 | SEQUENCE 长度,表示后续 70 字节(0x46 = 70)是序列内容。 |
3-5 | 022100 | INTEGER 标签和长度,表示 r 是一个 32 字节(0x21 = 33,含前缀 00 )的正整数。 |
6-37 | ... | r 的具体值(32 字节)。 |
38-40 | 022100 | INTEGER 标签和长度,表示 s 是一个 32 字节的正整数。 |
41-72 | ... | s 的具体值(32 字节)。 |
3. 关键字段说明
1) 3046
30
:ASN.1 的 SEQUENCE 标签(表示复合结构)。46
:序列的 总长度(70 字节),计算如下:r
部分:02
(标签) +21
(长度) +00
(前缀) + 32 字节 = 35 字节。s
部分:同上,35 字节。- 总计:35 + 35 = 70 字节 →
0x46
。
2) 022100
02
:ASN.1 的 INTEGER 标签。21
:整数的长度(33 字节,包含前缀00
)。00
:前缀字节(因r
/s
的最高位为 1,需补00
避免被当作负数)。
4. 为什么需要 00
前缀?
- 规则:若整数的最高位(MSB)为
1
,需补00
避免被误认为是负数(ASN.1 的 INTEGER 是带符号的)。 - 示例:
- 若
r
的第一个字节是0x8F
(二进制10001111
),需补00
变为008F...
。 - 若
r
的第一个字节是0x3F
(二进制00111111
),无需补00
。
- 若
5. 实际签名示例
假设签名值为:
3046022100A1B2C3...(32字节)022100D4E5F6...(32字节)
- 解析:
30 46
:SEQUENCE,长度 70 字节。02 21 00
:r
是 33 字节(含前缀00
),实际值 32 字节。A1B2C3...
:r
的具体数据。02 21 00
:s
是 33 字节(含前缀00
),实际值 32 字节。D4E5F6...
:s
的具体数据。
6. 代码验证(Java + Bouncy Castle)
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.util.encoders.Hex;public class SM2SignatureParser {public static void main(String[] args) {String derSignature = "3046022100A1B2C3...022100D4E5F6..."; // 示例签名byte[] signatureBytes = Hex.decode(derSignature);// 解析 DER 编码ASN1Sequence sequence = ASN1Sequence.getInstance(signatureBytes);BigInteger r = ((ASN1Integer) sequence.getObjectAt(0)).getValue();BigInteger s = ((ASN1Integer) sequence.getObjectAt(1)).getValue();System.out.println("r: " + r.toString(16));System.out.println("s: " + s.toString(16));}
}
五、补充:商用密码检测相关标准下载
1. GB/T 15843 国家标准(权限鉴别相关)
15843标准共分为6部分,第1部分为总则。
《GB∕T 15843.1-2017 信息技术 安全技术 实体鉴别 第1部分:总则.pdf》
《GB∕T 15843.2-2024 网络安全技术 实体鉴别 第2部分:采用鉴别式加密的机制.pdf》
《GB∕T 15843.3-2023 信息技术 安全技术 实体鉴别 第3部分:采用数字签名技术的机制.pdf》
《GB∕T 15843.4-2024 网络安全技术 实体鉴别 第4部分:采用密码校验函数的机制.pdf》
《GB∕T 15843.5-2005 信息技术 安全技术 实体鉴别 第5部分:使用零知识技术的机制.pdf》
《GB∕T 15843.6-2018 信息技术 安全技术 实体鉴别 第6部分:采用人工数据传递的机制.pdf》
下载地址: https://share.weiyun.com/bEAhW1Ec
如果只是为了检测时满足国家标准,最简单地可以参考第2部分的单次鉴别。
2. GB/T 38540国家标准(电子 签章相关,参考)
《GB∕T 38540-2020 信息安全技术 安全电子签章密码技术规范.pdf》
下载地址: https://share.weiyun.com/Mw2EwyZl
3. GM/T 0003 国密标准(SM2算法)
《GM∕T 0003-2010 SM2椭圆曲线公钥密码算法.pdf》
下载地址: https://share.weiyun.com/PvwgP2sM
4. GM/T 0031国密标准(电子签章相关,参考)
《GMT 0031-2014 安全电子签章密码技术规范.pdf》
下载地址: https://share.weiyun.com/VA5zlwVW
5.其余国家标准下载
全国网络安全标准化技术委员会:https://www.tc260.org.cn/front/bzcx/yfgbcx.html
(该地址可以下载国家标准文件,但是仅供参考,部分国家标准搜索不到。)
6. 其余国密标准下载
区别于国家标准有版权限制,国密标准可以直接在官方网站进行下载。
国家密码管理局-官网地址: https://www.oscca.gov.cn/sca/index.shtml
例如,我们下载SM3标准,可以先进行搜索,如下所示:
搜索之后可以看到下面有相关的文件,点击就可以直接下载了。
7. GB/T 38540 国家标准和 GM/T 0031 国密标准的应用场景差异:
场景 | GB/T 38540适用性 | GM/T 0031适用性 |
---|---|---|
国际化业务(如跨境电子合同) | ✅ 优先采用 | ❌ 不适用 |
政府/金融等关键领域 | 可选 | ✅ 强制符合 |
商用密码产品认证 | ❌ 无法用于过密评 | ✅ 必需符合 |
整理完毕,完结撒花~🌻
参考地址:
1.SM2 签名验签 注意事项,https://blog.csdn.net/softt/article/details/141570577
相关文章:
Java实现加密(七)国密SM2算法的签名和验签(附商用密码检测相关国家标准/国密标准下载)
目录 一、国密标准中,关于SM2签名验签的定义二、SM2签名和验签的实现原理1. 前置知识2. 签名生成过程3. 验签过程4. 数学正确性证明5. 安全性与注意事项 三、带userId、不带userId的区别1. 核心区别2.算法区别(1) 哈希计算过程(2) 签名验签流程 四、Java代码实现1. …...
贪心算法~~
目录 一、理论基础 二、题目练习 (1)455. 分发饼干 (2)53. 最大子数组和 - 力扣 (3)122. 买卖股票的最佳时机 II - 力扣(LeetCode) (4)860. 柠檬水找零…...
XYNU2024信安杯-REVERSE(复现)
前言 记录记录 1.Can_you_find_me? 签到题,秒了 2.ea_re 快速定位 int __cdecl main_0(int argc, const char **argv, const char **envp) {int v4; // [esp0h] [ebp-1A0h]const char **v5; // [esp4h] [ebp-19Ch]const char **v6; // [esp8h] [ebp-198h]char v7;…...
NLP系列【自然语言处理的深度学习模型综述】
自然语言处理的深度学习模型 摘要传统自然语言处理模型(略 不作重点)神经网络自然语言处理模型经典神经网络CNN网络模型Word2Vec模型RNN模型GPT网络模型BERT网络模型 BERT变体模型提升模型性能模型压缩 摘要 在自然语言处理任务方面,依据语料…...
【差分隐私】basic primitive的含义
在差分隐私领域,“basic primitive”一词具有特定的技术含义,需从单词本义及学科背景两个层面解析: 一、单词本义解析 “Primitive”在计算机科学中通常指代基础构建单元或核心组件,例如编程语言中的基本数据类型(如整…...
数字浪潮下的算力担当:GPU 服务器的多元应用、核心价值
在当今数据洪流和信息爆炸的时代,算力已成为衡量国家、行业乃至企业发展水平的关键指标。而算力服务器,特别是 GPU 服务器,作为算力的核心载体,正以其卓越性能深刻改变着世界的运行逻辑与模式。从数据处理到云计算,从人…...
【Echarts】使用echarts绘制多个不同类型的中国地图
一、需求 在同一页面上绘制多个不同类型的中国地图,如果是在同一页面上绘制多个同一种类型的地图可以直接引用一个china.js文件,设置两个独立的div分别用于放置两个地图,并实例化配置相关参数即可,但是如果在同一个页面上绘制多个…...
WEB漏洞-XSS跨站原理分类
本文主要内容 原理 XSS漏洞产生原理? XSS漏洞危害影响? 分类 反射型、存储型、DOM型 手法 XSS平台使用 XSS工具使用 XSS结合其他漏洞 靶场搭建 pikachu 靶场搭建(完整版)-CSDN博客https://blog.csdn.net…...
PR第二课--混剪
1.音乐打点 1.1 手动打点 按钮(如图),或者,快捷键M(如果在已有打点处,再次按M键会进入对标记点的设置界面,如下下图) 1.2 插件打点 一段音乐中,有明显的鼓点时,可以使用打点插件,快捷打点;如果鼓点不明显的话,最好还是手动打点,用插件打点会打出大量的标记点,…...
Kafka和flume整合
需求1:利用flume监控某目录中新生成的文件,将监控到的变更数据发送给kafka,kafka将收到的数据打印到控制台: 在flume/conf下添加.conf文件, vi flume-kafka.conf # 定义 Agent 组件 a1.sourcesr1 a1.sinksk1 a1.c…...
Linux 内核网络协议栈中 inet_stream_ops 与 tcp_prot 的深度解析
在 Linux 内核网络协议栈中,TCP 协议的实现依赖于多个关键结构体的协作。其中,inet_stream_ops 和 tcp_prot 是两个核心结构体,它们分别属于不同的层次,共同完成从用户态系统调用到底层协议处理的完整链路。本文将从功能定位、协作关系、代码示例及设计哲学等方面,深入分析…...
flume整合kafka
需求一: 启动flume 启动kafka消费者,验证数据写入成功 新增测试数据 需求二: 启动Kafka生产者 启动Flume 在生产者中写入数据...
EasyRTC音视频实时通话嵌入式SDK,打造社交娱乐低延迟实时互动的新体验
一、方案背景 在数字化时代,社交娱乐已经成为人们生活中不可或缺的一部分。随着移动互联网和智能设备的普及,用户对实时互动的需求越来越高。EasyRTC作为一款基于WebRTC技术的实时音视频通信解决方案,凭借其低延迟、高稳定性和跨平台兼容性&…...
制作一款打飞机游戏21:自定义工具
关于如何在Pico 8中创建我们自己的编辑器。 外部编辑器的需求 首先,我想谈谈为什么我们需要外部编辑器。外部编辑器通常用于编辑游戏中的数据。例如,一个游戏卡或程序通常包含一些代码,但也会包含数据,比如静态信息,…...
面向高性能运动控制的MCU:架构创新、算法优化与应用分析
摘要:现代工业自动化、汽车电子以及商业航天等领域对运动控制MCU的性能要求不断提升。本文以国科安芯的MCU芯片AS32A601为例,从架构创新、算法优化到实际应用案例,全方位展示其在高性能运动控制领域的优势与潜力。该MCU以32位RISC-V指令集为基…...
LWIP中两种重要的数据结构pbuf和pcb详细介绍
LWIP(Lightweight IP)是为嵌入式系统设计的轻量级TCP/IP协议栈。pbuf(Packet Buffer)和PCB(Protocol Control Block)是LwIP中两个核心数据结构,分别负责数据包管理和协议状态维护。 1. pbuf&…...
embedding_model模型通没有自带有归一化层该怎么处理?
embedding_model 是什么: 嵌入式模型(Embedding)是一种广泛应用于自然语言处理(NLP)和计算机视觉(CV)等领域的机器学习模型,它可以将高维度的数据转化为低维度的嵌入空间࿰…...
【蓝桥杯选拔赛真题104】Scratch回文数 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析
目录 scratch回文数 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 四、程序编写 五、考点分析 六、推荐资料 1、scratch资料 2、python资料 3、C++资料 scratch回文数 第十五届青少年蓝桥杯scratch编…...
1.2-1.3考研408计算机组成原理第一章 计算机系统概述
计算机组成原理第一章 计算机系统概述 一、计算机的层次结构 1.1 计算机系统组成 计算机系统由硬件系统和软件系统两大部分构成: 硬件系统:包括运算器、控制器、存储器、输入设备和输出设备五大核心部件(冯诺依曼体系结构)。软…...
【QQmusic自定义控件实现音乐播放器核心交互逻辑】第三章
🌹 作者: 云小逸 🤟 个人主页: 云小逸的主页 🤟 motto: 要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前,其次就是现在&…...
基于图扑 HT 实现的智慧展馆数字孪生应用
在当今数字化时代,智慧展览馆作为传统展览场所的创新升级形态,借助前沿科技与现代化管理理念,实现了全方位的数字化、智能化转型。图扑软件凭借其自主研发的 HT 技术在智慧展馆领域取得了卓越成果,为城市基础设施数字化应用带来了…...
从线性到非线性:简单聊聊神经网络的常见三大激活函数
大家好,我是沛哥儿,我们今天一起来学习下神经网络的三个常用的激活函数。 引言:什么是激活函数 激活函数是神经网络中非常重要的组成部分,它引入了非线性因素,使得神经网络能够学习和表示复杂的函数关系。 在神经网络…...
重生之--js原生甘特图实现
需求: 一个树形结构,根据子节点的时间范围显示显示进度 ,不同的时间范围对应不同的颜色 数据类型大概是这个样子的 甘特图 dom部分 首先要计算所有节点的 最大时间和最小时间 然后再计算每个甘特图的宽度 再计算他的偏移量 再计算颜色...
pnpm monoreop 打包时 node_modules 内部包 typescript 不能推导出类型报错
报错信息如下: ../../packages/antdv/components/pro-table/src/form-render.vue:405:1 - error TS2742: The inferred type of default cannot be named without a reference to .pnpm/scroll-into-view-if-needed2.2.31/node_modules/scroll-into-view-if-needed…...
告别默认配置!Xray自定义POC开发指南
文章涉及操作均为测试环境,未授权时切勿对真实业务系统进行测试! 下载与解压 官网地址: Xray GitHub Releases 根据系统选择对应版本: Windows:xray_windows_amd64.exe.zipLinux:xray_linux_amd64.zipmacOS:xray_darwin_amd64.zip解压后得到可执行文件(如 xray_linux_…...
websheet之 自定义函数
在线代码 {.is-success} 一、自定义函数约定 必须遵守本控件的自定函数约定才可以正常使用。 {.is-warning} 约定如下: 自定义类名称与函数名称一致。(强制)该类方法名称与函数名称一致,该方法是函数的入口。(强制&am…...
Jenkins Pipeline 构建 CI/CD 流程
文章目录 jenkins 安装jenkins 配置jenkins 快速上手在 jenkins 中创建一个新的 Pipeline 作业配置Pipeline运行 Pipeline 作业 Pipeline概述Declarative PipelineScripted Pipeline jenkins 安装 安装环境: Linux CentOS 10:Linux CentOS9安装配置Jav…...
电脑技巧:路由器内部元器件介绍
目录 1. 处理器(CPU) 2. 内存(RAM) 3. 固态存储(Flash Memory) 4. 网络接口卡(NIC) 5. 电源模块 6. 散热系统 7. 无线天线 结语 路由器是我们日常上网的重要设备,今天我们就来深入了解路由器内部的各个元器件,了解它们是如何协同工作,一起来看看吧。 1. 处理器(CPU…...
ArrayUtils:数组操作的“变形金刚“——让你的数组七十二变
各位数组操控师们好!今天给大家带来的是Apache Commons Lang3中的ArrayUtils工具类。这个工具就像数组界的"孙悟空",能让你的数组随心所欲地变大、变小、变长、变短,再也不用对着原生数组的"死板"叹气了! 一…...
电脑温度怎么看 查看CPU温度的方法
监测电脑温度对于保持硬件健康非常重要,特别是在进行高强度运算、游戏或超频等操作时。过高的温度可能导致硬件性能下降,甚至损坏。本篇文章将介绍查看电脑温度的4种方法。 一、使用Windows内置工具查看CPU温度 Windows系统本身并不直接提供查看CPU温度…...
【合新通信】---浸没式液冷光模块化学兼容性测试方法
一、测试目的与核心挑战 测试目标 验证冷媒(氟化液、矿物油等)与光模块材料的化学稳定性,确保长期浸没环境下无腐蚀、溶胀或性能衰减。关键风险点:密封材料(如硅胶、环氧树脂)的溶解或老化;金…...
shell 循环
shell 循环while语句,shell循环until语句在上一篇shell流程控制 1.shell循环until语句 until 条件 #当后面的条件表达式为假的时候的才循环,为真的时候就停止了 do 循环体 done [root@linux-server script]# cat until.sh (1) #!/bin/bash x=1 until [ $x -ge 10 ] 大于…...
【产品经理】常见的交互说明撰写方法
在产品原型设计中,交互说明是确保开发团队准确理解设计意图的关键文档。以下是常见的交互说明撰写方法及其应用场景,帮助您系统化地传达交互逻辑: 文字描述法 方法:用自然语言详细描述操作流程、反馈及规则。 适用场景ÿ…...
使用kubeadmin 部署k8s集群
成功搭建一个 Kubernetes 1.28.2 集群,包含以下组件和状态: 集群拓扑 1 个 Master 节点 IP:10.1.1.100 角色:control-plane 2 个 Worker 节点 Node2:10.1.1.101 Node3:10.1.1.102 核心组件状态 所有节点通过 kubectl get nodes 显示为 Ready。 核心 Pod(如 etc…...
二项式分布html实验
二项式分布html实验 本文将带你一步步搭建一个纯前端的二项分布 Monte-Carlo 模拟器。 只要一个 HTML 文件,打开就能运行: 动态输入试验次数 n、成功概率 p 与重复次数 m点击按钮立刻得到「模拟频数 vs 理论频数」柱状图随着 m 增大,两组柱状…...
[基础] Windows PCIe设备驱动框架与开发实践深度解析
Windows PCIe设备驱动框架与开发实践深度解析 1. PCIe设备驱动技术背景 PCI Express(Peripheral Component Interrupt Express)作为现代计算机系统的核心互连标准,其驱动程序开发涉及复杂的内核模式编程。Windows系统通过模块化的驱动架构支…...
面向智能家居安全的异常行为识别与应急联动关键技术研究与系统实现(源码+论文+部署讲解等)
需要资料,请文末系 一、平台介绍 3D家庭实景 - 动热力图 多模态看板 跌倒行为分析 二、论文内容 在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2dfe7f45d3ce42399e0df9535870d26d.png) bash 摘要 Abstract第一章 绪论 1.1 研究背景与动机 o1.1.1…...
根据JSON动态生成表单表格
根据JSON动态生成表单表格 一. 子组件 DynamicFormTable.vue1,根据JSON数据动态生成表单表格,支持表单验证JS部分1.1,props数据1.2,表单数据和数据监听1.3,自动验证1.4,表单验证1.5,获取表单数据1.6,事件处理1.7,暴露方法给父组件2,HTML部分二,父组件1, 模拟数据2,…...
spring OncePerRequestFilter 作用
概要 OncePerRequestFilter 是 Spring Web 提供的一个抽象滤器基类,用于保证在一次 HTTP 请求的整个分派过程中,该滤器仅执行一次,无论该请求经历了多少次内部转发(forward)、包含(include)或错…...
关于开源大模型(如 LLaMA、InternLM、Baichuan、DeepSeek、Qwen 等)二次开发或训练经验的关键点和概述
以下是适合初学者理解的关于开源大模型(如 LLaMA、InternLM、Baichuan、DeepSeek、Qwen 等)二次开发或训练经验的关键点和概述,: 关键点: 研究表明,二次开发通常涉及微调模型以适应特定任务,需…...
promethus基础
1.下载prometheus并解压 主要配置prometheus.yml文件 在scrape_configs配置项下添加配置(hadoop202是主机名): scrape_configs: job_name: ‘prometheus’ static_configs: targets: [‘hadoop202:9090’] 添加 PushGateway 监控配置 job_name: ‘pushgateway’…...
26考研 | 王道 | 数据结构 | 第八章 排序
第八章 排序 文章目录 第八章 排序**8.1** 排序的基本概念**8.2 插入排序****8.2.1 直接插入排序****8.2.2 折半插入排序****8.2.3 希尔排序** 8.3 交换排序8.3.1 冒泡排序8.3.2 快速排序 8.4 选择排序8.4.1 简单选择排序8.4.2 堆排序堆的概念:建立大根堆的代码堆排…...
SecMulti-RAG:兼顾数据安全与智能检索的多源RAG框架,为企业构建不泄密的智能搜索引擎
本文深入剖析SecMulti-RAG框架,该框架通过集成内部文档库、预构建专家知识以及受控外部大语言模型,并结合保密性过滤机制,为企业提供了一种平衡信息准确性、完整性与数据安全性的RAG解决方案,同时有效控制部署成本。 企业环境中A…...
kubesphere 单节点启动 etcd 报错
kubekey安装 ./kk create cluster -f config-sample.yaml --with-local-storage 时报错 etcd health check failed: Failed to exec command: sudo -E /bin/bash -c "export ETCDCTL_API2;export ETCDCTL_CERT_FILE/etc/ssl/etcd/ssl/admin-node1.pem;export ETCDCTL_KEY_…...
femap许可常见问题及解决方案
在使用Femap进行电磁仿真分析时,许可证管理是一个关键环节。然而,许多用户在许可证使用过程中可能会遇到各种问题。本文旨在解答关于Femap许可的常见疑问,并提供相应的解决方案,帮助您更顺畅地使用Femap许可证。 一、常见问题 许…...
游戏引擎学习第244天: 完成异步纹理下载
启动并运行游戏,注意到我们的纹理没有被下载 我们将继续完成游戏的开发。昨天,我们已经实现了多线程的纹理下载,但并没有时间调试它,因此纹理下载功能目前并没有正常工作。我们只是写了相关的代码,但由于大部分时间都…...
【安全扫描器原理】TCP/IP协议编程
【安全扫描器原理】TCP/IP协议编程 1.概述2.Windows Socket结构3.Windows socket转换类函数4.Windows Socket通信类函数 1.概述 TCP/IP协议是目前网络中使用最广泛的协议,Socket称为“套接口”,最早出现在Berkeley Unix中,最初只支持TCP/I…...
Cuda-GDB Frame Unwind 管理(未完.)
在计算机编程中,Frame Unwind(栈展开) 是指函数调用栈的逆向操作,即在函数返回或异常发生时,系统逐层释放栈帧(Stack Frame)、恢复调用上下文的过程。以下是详细解释及其在 GPU编程(…...
如何在IDEA中高效使用Test注解进行单元测试?
在软件开发过程中,单元测试是保证代码质量的重要手段之一。而IntelliJ IDEA作为一款强大的Java开发工具,提供了丰富的功能来支持JUnit测试,尤其是通过Test注解可以快速编写和运行单元测试。那么,如何在IDEA中高效使用Test注解进行…...
什么是访客鉴权?全面解析核心原理与CC防护应用实践
一、访客鉴权是什么? 访客鉴权(Visitor Authentication and Authorization)是系统对访问者进行身份验证和权限控制的过程,确保只有合法用户能够访问特定资源或执行特定操作。其核心目标是确认身份、控制权限、保障数据安全&#…...