当前位置: 首页 > article >正文

Java国密SM2证书Unknown curve异常的三步绕过方案

1. 这不是JDK的bug是国密算法在Java生态里“没户口”的真实写照你刚把SM2证书集成进Spring Boot服务调用验签接口时控制台突然炸出一行红字java.security.InvalidKeyException: Unknown curve。接着堆栈里全是sun.security.ec.ECParameters.decodeNamedCurveOid、ECKeyFactory.engineGeneratePublic这类底层类名——你立刻去查JDK文档发现JDK 8u261、JDK 11、JDK 17都明确写了“支持SM2”但现实就是死活不认你的证书。这不是你代码写错了也不是证书生成有问题而是Java原生密码学体系里压根没给SM2曲线分配一个合法的OID注册位。国密算法在OpenSSL里是头等公民在国密USB Key里是出厂标配但在JDK的sun.security.ec包里它连个“临时居住证”都没有。这个问题背后是国产密码算法落地Java生态时最典型的“标准断层”国家密码管理局发布的GM/T 0003-2012《SM2椭圆曲线公钥密码算法》定义了1.2.156.10197.1.301这个OID而JDK直到2023年发布的JDK 21才通过JEP 436Vector API附带补丁式支持该OID更早版本的JDK包括长期主力JDK 8/11/17默认只认NIST曲线如secp256r1对应OID1.2.840.10045.3.1.7对国密OID直接抛Unknown curve异常。这不是配置疏漏是JDK密码提供者SunEC的硬编码白名单缺失。我去年帮三家政务云平台做等保三级改造时全卡在这个点上——他们用的是统一采购的国密CA签发的SM2证书后端Java服务却连验签第一步都过不去。最终解决方案不是升级JDK生产环境不敢贸然升到JDK 21而是用三步“外科手术式”兼容绕过JDK原生EC参数解析逻辑接管公钥构造过程注入国密OID映射规则。这篇文章就带你亲手完成这三步不依赖任何商业SDK纯JDKBCBouncy Castle组合实测在JDK 8u291、JDK 11.0.18、JDK 17.0.7上全部跑通且完全符合GM/T 0003-2012和GB/T 32918.2-2016标准。2. 深度拆解Unknown curve报错的根源从ASN.1结构到JDK源码级定位2.1 SM2证书的公钥字段到底长什么样要理解为什么JDK会报Unknown curve必须先看清SM2证书里那个被拒绝的公钥数据结构。我们用OpenSSL命令导出证书公钥部分openssl x509 -in sm2_cert.pem -pubkey -noout | openssl asn1parse -i输出关键片段如下0:d0 hl4 l 290 cons: SEQUENCE 4:d1 hl2 l 1 prim: INTEGER :00 7:d1 hl4 l 285 cons: SEQUENCE 11:d2 hl2 l 7 prim: OBJECT :id-ecPublicKey 20:d2 hl2 l 9 prim: OBJECT :sm2p256v1 -- 注意这里 31:d2 hl4 l 263 cons: cont [ 0 ] 35:d3 hl4 l 259 prim: BIT STRING重点看第20行OBJECT :sm2p256v1。这个sm2p256v1不是字符串别名而是RFC 5480定义的OID别名其真实值为1.2.156.10197.1.301。而JDK的sun.security.ec.ECParameters.decodeNamedCurveOid方法内部维护了一个静态Mapprivate static final MapString, NamedCurve oidMap new HashMap(); static { oidMap.put(1.2.840.10045.3.1.7, NamedCurve.secp256r1); oidMap.put(1.2.840.10045.3.1.35, NamedCurve.secp384r1); oidMap.put(1.2.840.10045.3.1.41, NamedCurve.secp521r1); // ... 全是NIST曲线没有1.2.156.10197.1.301 }当JDK解析到sm2p256v1OID时尝试从oidMap中get结果返回null于是直接抛出InvalidKeyException(Unknown curve)。这个逻辑在JDK 8u261到JDK 17所有版本中完全一致源码路径为src/share/classes/sun/security/ec/ECParameters.java第142行附近。2.2 为什么Bouncy Castle也救不了你——Provider加载顺序的致命陷阱你可能立刻想到“加BC Provider不就完了”确实Bouncy Castle 1.70版本完整实现了SM2算法并注册了1.2.156.10197.1.301OID。但问题在于JDK默认使用SunEC Provider处理EC公钥解析而BC Provider根本没机会介入这个阶段。我们验证一下Provider加载顺序Security.getProviders().forEach(p - System.out.println(p.getName() - p.getService(KeyFactory, EC)));输出典型结果SUN - sun.security.ec.ECKeyFactory SunRsaSign - null BC - org.bouncycastle.crypto.params.ECDomainParameters注意SUNProvider的ECKeyFactory服务存在而BCProvider虽然注册了EC相关服务但它的KeyFactory实现类名是org.bouncycastle.jce.provider.JCEECKeyFactory且其engineGeneratePublic方法只处理X509EncodedKeySpec不处理ECParameterSpec。更重要的是JDK的KeyFactory.getInstance(EC)默认走SUNProvider除非显式指定// ❌ 这样还是走SUN Provider KeyFactory kf KeyFactory.getInstance(EC); // ✅ 必须强制指定BC Provider KeyFactory kf KeyFactory.getInstance(EC, BC);但问题来了证书验签通常由Signature类触发而Signature.getInstance(SM3withSM2)内部会自动调用KeyFactory.getInstance(EC)你无法干预这个内部调用链。所以单纯加BC Provider只是让“能算SM2签名”这件事成立但“解析SM2证书公钥”这个前置步骤依然卡死在SunEC的OID黑名单里。2.3 真正的突破口绕过KeyFactory直操作ECPoint与ECParameterSpec既然KeyFactory这条路被SunEC堵死我们就得另辟蹊径。SM2公钥本质是一个椭圆曲线上的点ECPoint而曲线参数ECParameterSpec可以手动构造。只要我们能从证书的DER编码中提取出原始的X/Y坐标字节再配上正确的SM2曲线参数就能手动构建ECPublicKey对象彻底绕过KeyFactory的OID校验。SM2曲线参数在GM/T 0003-2012中明确定义p FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFF67 (modulus)a FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFF64 (coefficient)b 28E9FA9E 9D9F5E34 4D5A9E4B CAF55000 5EDABCD3 3376892B 1B87120B 12E24105 (coefficient)G 32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7 (base point x)BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0 (base point y)n FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE 5EBAFEFF FFFFFFFF FFFFFFFF FFFFFFFF (order)这些十六进制值正是我们手动构造ECParameterSpec的全部依据。接下来三步就是基于这个原理的实操落地。3. 第一步提取证书公钥原始坐标——用ASN.1解析器精准定位BIT STRING内容3.1 为什么不能直接用X509Certificate.getPublicKey()这是绝大多数人踩的第一个坑。当你调用X509Certificate cert (X509Certificate) cf.generateCertificate(new FileInputStream(sm2_cert.pem)); PublicKey pk cert.getPublicKey(); // ❌ 这里就抛Unknown curve了JDK在X509CertificateImpl.getPublicKey()内部会立即调用KeyFactory.getInstance(EC).generatePublic(spec)而spec正是从证书ASN.1中解析出的ECParameterSpec其中包含sm2p256v1OID——此时异常已发生根本没机会执行后续逻辑。所以必须在JDK解析之前用底层ASN.1解析器直接读取证书DER字节跳过所有高级API。3.2 手动解析DER定位公钥BIT STRING的起始偏移量SM2证书的公钥存储在SubjectPublicKeyInfo结构中其ASN.1定义为SubjectPublicKeyInfo :: SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING }其中algorithm包含OIDsubjectPublicKey才是真正的公钥坐标。我们需要跳过algorithm部分直接读取subjectPublicKey的原始字节。以下是零依赖的纯Java实现无需BC仅用JDK内置DerInputStreamimport sun.security.util.DerInputStream; import sun.security.util.DerValue; public class Sm2CertParser { public static byte[] extractRawPublicKey(byte[] certDer) throws Exception { DerInputStream dis new DerInputStream(certDer); DerValue[] seq dis.getSequence(2); // 外层SEQUENCE含2个元素 // 第一个元素AlgorithmIdentifier (SEQUENCE) DerValue algId seq[0]; DerInputStream algDis algId.toDerInputStream(); DerValue[] algSeq algDis.getSequence(2); // algSeq[0] 是OIDalgSeq[1] 是NULL或参数我们忽略 // 第二个元素subjectPublicKey (BIT STRING) DerValue pubKeyBitString seq[1]; byte[] bitStringData pubKeyBitString.getBitString(); // 自动去掉bitstring header // SM2公钥格式0x04 || X || Y共65字节X 32字节 Y 32字节 0x04前缀 if (bitStringData.length ! 65 || bitStringData[0] ! 0x04) { throw new IllegalArgumentException(Invalid SM2 public key format); } // 提取X和Y坐标各32字节 byte[] xBytes new byte[32]; byte[] yBytes new byte[32]; System.arraycopy(bitStringData, 1, xBytes, 0, 32); System.arraycopy(bitStringData, 33, yBytes, 0, 32); return new byte[][]{xBytes, yBytes}; // 返回二维数组[0]X, [1]Y } }这段代码的关键点使用sun.security.util.DerInputStreamJDK内部类非公开API但稳定可用生产环境经受住考验getBitString()方法自动剥离ASN.1 BIT STRING的头部长度字节未使用位数返回纯净的公钥字节严格校验SM2公钥格式必须是65字节首字节为0x04表示未压缩格式确保后续构造ECPoint时不会出错提示sun.*包虽属内部API但在JDK 8/11/17中行为完全一致且此解析逻辑不涉及密码运算仅做字节提取风险极低。若团队强要求避免内部API可用Bouncy Castle的ASN1InputStream替代但需额外引入BC依赖。3.3 实测验证用真实SM2证书跑通坐标提取我用CFCA国密CA签发的真实SM2证书证书序列号1234567890ABCDEF测试上述代码byte[] certBytes Files.readAllBytes(Paths.get(cfca_sm2_cert.der)); byte[][] coords Sm2CertParser.extractRawPublicKey(certBytes); System.out.println(X: Hex.toHexString(coords[0])); System.out.println(Y: Hex.toHexString(coords[1]));输出X: 3a7b8c9d... (32字节十六进制) Y: 1f2e3d4c... (32字节十六进制)与OpenSSL命令openssl ec -in sm2_cert.pem -pubin -text -noout显示的公钥坐标完全一致。这证明我们成功绕过了JDK的OID校验拿到了最原始的数学坐标。4. 第二步手动生成SM2曲线参数——用BigInteger精确构造ECParameterSpec4.1 为什么不能用ECNamedCurveTable.getByName(sm2p256v1)Bouncy Castle提供了便捷的曲线表X9ECParameters params ECNamedCurveTable.getByName(sm2p256v1); // ✅ 正确 // 或 X9ECParameters params ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(1.2.156.10197.1.301));但问题在于X9ECParameters是BC自己的类型而JDK的ECPublicKey需要ECParameterSpecJDK标准类。我们必须把BC的X9ECParameters转换成JDK原生的ECParameterSpec且确保所有BigInteger值100%匹配GM/T 0003-2012标准。4.2 手动构造ECParameterSpec逐字段对照国密标准根据GM/T 0003-2012SM2曲线sm2p256v1的参数必须严格如下十六进制字符串转BigInteger参数十六进制值截取前32字符说明pFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFF67模数aFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFF64曲线系数ab28E9FA9E 9D9F5E34 4D5A9E4B CAF55000 5EDABCD3 3376892B 1B87120B 12E24105曲线系数bGx32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7基点X坐标GyBC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0基点Y坐标nFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE 5EBAFEFF FFFFFFFF FFFFFFFF FFFFFFFF阶下面是完整的构造代码无BC依赖纯JDKimport java.math.BigInteger; import java.security.spec.ECFieldFp; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; public class Sm2CurveBuilder { // SM2标准参数来自GM/T 0003-2012 private static final String P_HEX FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67; private static final String A_HEX FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64; private static final String B_HEX 28E9FA9E9D9F5E344D5A9E4BCAF550005EDABCD33376892B1B87120B12E24105; private static final String GX_HEX 32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7; private static final String GY_HEX BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0; private static final String N_HEX FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5EBAFEFFF0000000000000000000000; public static ECParameterSpec buildSm2ParameterSpec() { BigInteger p new BigInteger(P_HEX, 16); BigInteger a new BigInteger(A_HEX, 16); BigInteger b new BigInteger(B_HEX, 16); BigInteger gx new BigInteger(GX_HEX, 16); BigInteger gy new BigInteger(GY_HEX, 16); BigInteger n new BigInteger(N_HEX, 16); // 构造椭圆曲线y^2 x^3 ax b (mod p) EllipticCurve curve new EllipticCurve(new ECFieldFp(p), a, b); // 构造基点G ECPoint g new ECPoint(gx, gy); // 构造ECParameterSpec指定cofactor1SM2标准 return new ECParameterSpec(curve, g, n, 1); } }这段代码的严谨性体现在所有十六进制字符串直接复制自GM/T 0003-2012标准原文杜绝手误ECFieldFp(p)明确指定为素域符合SM2定义cofactor1是SM2强制要求NIST曲线常用cofactor1但必须显式声明返回的ECParameterSpec是JDK标准类型可被任何JDK组件识别4.3 验证参数正确性用OpenSSL交叉比对我们用OpenSSL生成一个SM2密钥对导出其参数openssl ecparam -name sm2p256v1 -genkey -noout -out sm2.key openssl ec -in sm2.key -text -noout输出中ASN1 OID: sm2p256v1下的Field Type,Prime,A,B,Generator等字段与我们代码中P_HEX,A_HEX,B_HEX,GX_HEX,GY_HEX的值完全一致。这证明手动构造的ECParameterSpec100%符合国密标准不是“差不多就行”而是“一字不差”。5. 第三步组装ECPublicKey并完成验签——打通最后一公里5.1 用ECPoint和ECParameterSpec手动构建公钥有了原始坐标X/Y字节和SM2曲线参数ECParameterSpec现在可以绕过KeyFactory直接构造ECPublicKeyimport java.math.BigInteger; import java.security.KeyFactory; import java.security.PublicKey; import java.security.spec.ECPoint; import java.security.spec.ECPublicKeySpec; import java.security.spec.X509EncodedKeySpec; public class Sm2PublicKeyBuilder { public static PublicKey buildFromCoordinates(byte[] xBytes, byte[] yBytes, ECParameterSpec spec) throws Exception { BigInteger x new BigInteger(1, xBytes); // 1表示正数避免高位为1被误判为负数 BigInteger y new BigInteger(1, yBytes); ECPoint w new ECPoint(x, y); ECPublicKeySpec keySpec new ECPublicKeySpec(w, spec); // 关键必须用BC Provider的KeyFactory因为SunEC不认SM2参数 KeyFactory kf KeyFactory.getInstance(EC, BC); return kf.generatePublic(keySpec); } }注意三点BigInteger(1, bytes)中的1是signum参数确保X/Y被解释为正整数SM2坐标必为正ECPublicKeySpec接受ECPoint和ECParameterSpec这是JDK标准构造方式KeyFactory.getInstance(EC, BC)显式指定BC Provider因为BC的JCEECKeyFactory能正确处理SM2参数5.2 完整验签流程从证书到Signature.verify()现在整合前三步写出可直接运行的验签方法import java.io.FileInputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.security.*; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.ECParameterSpec; import java.util.Base64; public class Sm2SignatureVerifier { public static boolean verify(String certPath, String signatureBase64, String data) throws Exception { // Step 1: 提取原始坐标 byte[] certBytes Files.readAllBytes(Paths.get(certPath)); byte[][] coords Sm2CertParser.extractRawPublicKey(certBytes); // Step 2: 构造SM2曲线参数 ECParameterSpec sm2Spec Sm2CurveBuilder.buildSm2ParameterSpec(); // Step 3: 组装公钥 PublicKey publicKey Sm2PublicKeyBuilder.buildFromCoordinates( coords[0], coords[1], sm2Spec); // Step 4: 执行验签使用BC的SM2签名算法 Signature signature Signature.getInstance(SM3withSM2, BC); signature.initVerify(publicKey); signature.update(data.getBytes(UTF-8)); byte[] sigBytes Base64.getDecoder().decode(signatureBase64); return signature.verify(sigBytes); } // 测试入口 public static void main(String[] args) throws Exception { boolean result verify( cfca_sm2_cert.der, MEYCIQD..., // base64 encoded SM2 signature Hello SM2 World ); System.out.println(验签结果: result); // true } }这段代码的生产就绪性体现在零异常穿透整个流程不经过X509Certificate.getPublicKey()彻底规避Unknown curveProvider隔离Signature.getInstance(SM3withSM2, BC)确保签名算法也走BC避免SunEC不支持SM3哈希字符集安全data.getBytes(UTF-8)显式指定编码防止中文乱码导致验签失败5.3 生产环境部署要点Provider注册与线程安全在Spring Boot应用中需在启动时注册BC ProviderSpringBootApplication public class Application { public static void main(String[] args) { // 在Spring容器初始化前注册BC Provider Security.addProvider(new BouncyCastleProvider()); SpringApplication.run(Application.class, args); } }注意Security.addProvider()是线程安全的且只需执行一次。不要在每次验签时重复注册否则会导致Provider列表膨胀。另外Sm2CurveBuilder.buildSm2ParameterSpec()是纯计算无状态可安全缓存public class Sm2CurveBuilder { private static final ECParameterSpec SM2_SPEC buildSm2ParameterSpec(); public static ECParameterSpec getSm2ParameterSpec() { return SM2_SPEC; // 单例复用避免重复构造 } }6. 常见问题与避坑指南那些文档里不会写的实战细节6.1 问题验签总是false但OpenSSL验签成功这是最典型的“数据格式不一致”问题。SM2签名在不同实现中可能采用不同编码DER编码标准ASN.1格式SEQUENCE { r INTEGER, s INTEGER }纯字节拼接r_bytes || s_bytes各32字节共64字节Bouncy Castle默认使用DER编码而某些国密设备如USB Key可能输出纯字节。验证方法// 检查签名字节长度 if (sigBytes.length 64) { // 纯字节格式需转换为DER byte[] derSig convertRawToDer(sigBytes); return signature.verify(derSig); } else if (sigBytes.length 64) { // DER格式直接使用 return signature.verify(sigBytes); }convertRawToDer实现需遵循DER编码规则此处略去实际项目中已封装为工具类。6.2 问题JDK 17报错Could not generate DH keypair与SM2无关却阻塞启动这是JDK 17的已知BugJDK-8274527当BC Provider注册后JDK的KeyPairGenerator.getInstance(DiffieHellman)会错误地尝试用BC Provider生成DH密钥而BC的DH实现与JDK不兼容。解决方案是在注册BC Provider时排除DH服务BouncyCastleProvider bcProvider new BouncyCastleProvider(); // 移除DH相关服务保留EC/SM2 bcProvider.remove(KeyPairGenerator.DiffieHellman); bcProvider.remove(KeyAgreement.DiffieHellman); Security.addProvider(bcProvider);6.3 问题证书链验签失败提示unable to find valid certification pathSM2证书链验签需确保所有中间CA证书也使用SM2算法。如果根CA是RSA证书而中间CA是SM2则JDK会因算法不一致拒绝构建信任链。解决方案要么全部使用SM2证书推荐符合等保要求要么在TrustManager中自定义验证逻辑对SM2证书单独处理需重写X509TrustManager6.4 性能优化公钥解析缓存策略在高并发场景下重复解析同一证书会成为瓶颈。建议按证书指纹SHA-256缓存公钥private static final LoadingCacheString, PublicKey PUBKEY_CACHE Caffeine.newBuilder() .maximumSize(1000) .expireAfterWrite(1, TimeUnit.HOURS) .build(Sm2SignatureVerifier::loadPublicKeyFromCert); private static PublicKey loadPublicKeyFromCert(String certFingerprint) throws Exception { // 根据指纹找到证书文件执行前三步解析 }实测表明缓存后单次验签耗时从15ms降至0.8msJDK 11Intel i7。7. 后续演进从“能用”到“好用”的三个方向这套方案解决了“Unknown curve”的燃眉之急但在大型项目中还需进一步工程化7.1 方向一集成到Spring Security实现PreAuthorize(hasRole(SM2_USER))目前验签是手动调用下一步应封装为Spring Security的AuthenticationProvider将SM2证书解析为Authentication对象从而支持注解式权限控制。核心是重写authenticate()方法在其中执行前三步公钥提取与验签。7.2 方向二支持国密SSL/TLS双向认证当前方案只解决应用层验签而国密合规要求HTTPS也使用SM2证书。这需要配置Tomcat/Jetty的SSLHostConfig并设置SSLEngine使用BC的TLSSM2ServerProtocol。难点在于JDK的SSLSocketFactory不识别SM2必须用BC的TlsClientProtocol重写HTTP客户端。7.3 方向三硬件密码机HSM集成生产环境敏感私钥不应存于JVM内存而应交由国密HSM管理。此时验签流程变为应用发送待验签数据证书 → HSM返回验签结果。需对接HSM厂商的Java SDK如江南天安、卫士通其SDK通常提供SM2Verify方法内部已处理OID兼容问题。我在某省政务云项目中实践过第三条将上述Java验签逻辑替换为HSM SDK调用性能提升3倍HSM硬件加速且完全规避了JDK版本限制。这印证了一个经验国密落地的终极形态不是在JDK里打补丁而是让JDK成为HSM的客户端。最后分享一个小技巧在Sm2CertParser.extractRawPublicKey()中加入日志记录每次解析的X/Y坐标前8字节。当验签失败时对比OpenSSL输出的坐标能瞬间定位是证书问题还是代码问题——这招帮我快速排查了70%的现场故障。

相关文章:

Java国密SM2证书Unknown curve异常的三步绕过方案

1. 这不是JDK的bug,是国密算法在Java生态里“没户口”的真实写照你刚把SM2证书集成进Spring Boot服务,调用验签接口时控制台突然炸出一行红字:java.security.InvalidKeyException: Unknown curve。接着堆栈里全是sun.security.ec.ECParameter…...

函数指针调用的两种语法及其在嵌入式C中的应用

1. 函数指针调用:两种语法背后的故事在嵌入式C开发中,函数指针是实现回调机制、插件架构和动态行为的关键技术。最近有工程师发现,通过函数指针调用函数时存在两种看似不同的语法形式:(*ptr)(); // 传统间接调用语法 ptr(); …...

CVE二进制工具:无源码漏洞检测的原理与实战

1. 这不是又一个“扫扫就完事”的漏洞扫描器很多人第一次听说“CVE二进制工具”时,下意识会把它和常见的Web漏洞扫描器(比如Nessus、OpenVAS)划等号——点几下鼠标,跑个任务,出份PDF报告,然后发给安全部门交…...

小学期学习——第二周

一、本周学习视频6-7学习了单电源供电的二阶低通滤波器以及电子计数法,并对仿真进行了改进。二、绘制了PCB原理图学习使用嘉立创EDA,并且绘制了PCB原理图。...

第 12 周 周报

牛 客 :周赛144,DEF C F :(dive2 1097) C D (dive2 1098)B (dive2 1099)BCD...

瑞德克斯在手机端的表现稳不稳?是否适合随时查看行情?

瑞德克斯在手机端的表现稳不稳?是否适合随时查看行情?移动端是当下用户接触金融服务最频繁的入口之一。瑞德克斯在手机端的体验打磨上下了不少功夫,让常用功能可以在小屏幕上同样得到清晰、舒适的呈现。瑞德克斯的移动应用采用了简洁的导航设…...

安全合规:满足行业安全标准和法规要求

安全合规:满足行业安全标准和法规要求 一、安全合规概述 1.1 安全合规的定义 安全合规是指企业在信息安全方面遵守相关法规、标准和行业规范的过程。它涉及数据保护、隐私安全、访问控制等多个方面,确保企业信息系统的安全性和合规性。 1.2 安全合规的价…...

从黑猩猩内战到人类关系:互动是系统的命脉,遗忘是文明的暗礁

从黑猩猩内战到人类关系:互动是系统的命脉,遗忘是文明的暗礁 将黑猩猩Ngogo群体从平和共处走向相互屠戮的演变过程,结合人类关系分型自相似性理论对照分析,一套完整的认知逻辑就此显现。江河支流汇聚、树木枝杈生长,乃…...

Go语言内存泄漏:pprof与监控

Go语言内存泄漏:pprof与监控 1. 内存泄漏检测 go tool pprof http://localhost:6060/debug/pprof/heap2. 总结 定期使用pprof检测内存使用,及时发现泄漏。...

Qt6.5数控加工CAM框架实战:基于工厂模式与分层架构的CamCore完整实现

文章简介 本文基于Qt Creator 14.0.1、Qt6.5 LTS、CMake、C17,搭建一套轻量化数控加工CAM核心框架CamCore。采用工序、算法、UI界面一一映射的分层架构,结合工厂模式、多态继承、枚举参数管控设计,具备参数管理、工艺模板复用能力&#xff0…...

股市学习心得-技术指标学习(布林线+MACD)

技术指标学习(布林线MACD)(所提供内容仅用于学习交流,不作为股市交易依据)首先,技术指标除了量比和换手率,都有滞后和造假的可能,因此不能用单一指标判断,也需要通过多个指标辅助决策。布林线MA…...

用Python和Pandas搞定泰坦尼克号数据集:从数据清洗到特征工程的完整实战

用Python和Pandas征服泰坦尼克号数据集:从数据清洗到特征工程的实战指南当第一次打开泰坦尼克号数据集时,那些密密麻麻的乘客信息就像一艘沉船上的碎片——杂乱无章却又充满故事。作为数据科学领域最经典的入门数据集,它包含了891名乘客的12个…...

避坑指南:处理NOAA海温数据时,关于陆地掩膜、时间解析和面积加权的三个常见错误

NOAA海温数据处理实战:避开陆地掩膜、时间解析与面积加权的三大陷阱当分析NOAA OISST海温数据时,许多研究者会不自觉地掉进几个技术陷阱——这些错误看似微小,却足以让整个分析结果偏离真实。我曾亲眼见过一位同行因为忽略纬度权重校正&#…...

避坑指南:用SARIMA做时间序列预测时,这5个参数调优错误千万别犯(Python实战)

SARIMA模型调优实战:避开时间序列预测中的五大陷阱引言在数据分析领域,时间序列预测一直是个既迷人又充满挑战的课题。每当我看到那些起伏的曲线,总能感受到数据背后隐藏的故事和规律。SARIMA模型作为时间序列分析的重要工具,因其…...

从‘交并比’到损失函数:一文搞懂Dice Loss在图像分割里的前世今生与代码实现

从集合相似度到像素级优化:Dice Loss在图像分割中的数学本质与工程实践当你在显微镜下观察一张病理切片时,那些蜿蜒交错的细胞边界决定了诊断结果;当自动驾驶汽车识别前方障碍物时,每个像素的分类关乎生命安全。图像分割作为计算机…...

单向晶闸管调压电路基础知识及Multisim电路仿真

目录 2.1.4 单向晶闸管调压电路 2.1.4.1 单向晶闸管调压电路基础知识 1. 电路结构与核心器件 2. 工作原理(核心逻辑) 3. 调压的本质:移相控制 2.1.4.2 单向晶闸管调压电路基础知识 1. 触发角 α = 0 2. 触发角 α = 90 3. 触发角 α = 180(第三张图) 总结对比 摘…...

2026年AI模型接口中转站真实测评:五大主流大模型API聚合平台深度实测调研指南

进入2026年,大语言模型的工程化落地已经走完从尝鲜到规模化普及的全流程,对于广大AI应用开发者而言,AI大模型接口中转站早就不是过去仅承担接口转发的简单工具,如今它已经承担起链路高可用保障、多模型负载均衡、跨协议自动转换等…...

2026年AI模型接口中转站全网全维度硬核实测 面向开发者与企业的权威选型实用指南

本次测评由中国产业信息研究院联合TechInsight AI评测实验室在2026年3月28日正式对外发布,所有公开统计数据全部来源于72小时不间断连续压测、万级QPS高并发仿真模拟、10万真实业务请求样本以及服务商后台脱敏运营数据,所有测试环节完全贴合真实生产场景…...

【STM32 C 语言入门】什么是强制类型转换?小白也能秒懂!

一、什么是强制类型转换?一句话讲透 强制类型转换,就是“强行把一种数据类型,变成另一种数据类型”。 打个比方: 你手里拿着一个苹果(int类型)但函数只收橙子(枚举类型)强制类型转换…...

3D光学流技术在机器人动作生成中的应用与优化

1. 3D光学流技术解析与机器人动作生成3D光学流技术是计算机视觉领域的重要突破,它通过分析物体在三维空间中的连续运动轨迹,为机器人动作规划提供了前所未有的精确度。传统2D光学流仅能捕捉平面运动信息,而3D光学流则能完整重建物体在XYZ三个…...

从‘看山是山’到‘看山不是山’:手把手教你用Landsat8波段组合玩转地物‘透视’

给地球戴上X光眼镜:Landsat8波段组合的视觉魔法手册第一次接触遥感影像的人,常会惊讶于同一片土地在不同"滤镜"下竟能呈现截然不同的面貌——茂密的森林在某张图上如火炬般鲜红耀眼,在另一张图中却消失不见;平静的湖面时…...

Nsight System和Compute命令行

Nsight System分析 nsys profile --tracecuda,nvtx --gpu-metrics-devicesall -o <out_file_name> python <python_file_name> <python args>示例 nsys profile --tracecuda,nvtx --gpu-metrics-devicesall -o profile_attention_bm128_bn64_w4_s2 python my…...

从集合运算到代码:一文搞懂Jaccard系数,附Python/NumPy/Pandas三种实现方法对比

从集合运算到代码&#xff1a;一文搞懂Jaccard系数&#xff0c;附Python/NumPy/Pandas三种实现方法对比在数据挖掘和机器学习领域&#xff0c;衡量两个集合的相似度是一项基础而重要的任务。Jaccard相似系数作为一种简单直观的度量方法&#xff0c;广泛应用于推荐系统、文本挖掘…...

不用开WPS会员了!这一款电子发票批量打印工具:支持排版 + OCR识别,完全免费!

软件下载 夸克下载&#xff1a;https://pan.quark.cn/s/39d9ed085809 软件介绍 今天给大家带来的是Office的代替品&#xff0c;LibreOffice不用激活、完全免费&#xff0c;非常好用&#xff01; 软件支持Windows、macOS、Linux。它包括包含 Writer&#xff08;文字处理&…...

MNIST识别项目复盘:除了准确率97%,我们更应该关注数据预处理与损失函数的选择

MNIST识别项目深度复盘&#xff1a;超越97%准确率的工程实践思考 在完成一个基础的MNIST手写数字识别项目后&#xff0c;很多开发者会满足于模型达到97%的准确率便止步不前。然而&#xff0c;真正有价值的机器学习实践远不止于调出一个高准确率的模型。本文将带您深入两个常被忽…...

人工智能通识课:深度学习框架 PyTorch

深度学习框架是连接算法理论与工程实践的重要工具。它让开发者不必从零实现张量运算、自动求导、参数更新、GPU 调度和模型保存等底层细节&#xff0c;而可以把主要精力放在数据处理、模型结构设计、训练策略和实验验证上。在众多深度学习框架中&#xff0c;PyTorch 凭借直观的…...

LLM:大语言模型的主要任务

大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;是以深度学习为基础、通过大规模文本或多模态数据训练得到的生成式模型。它的核心能力并不是完成某一个固定任务&#xff0c;而是围绕语言理解、文本生成、信息处理、推理协助、代码生成、工具调用和多模…...

AI 术语通俗词典:RAG

RAG 是大语言模型、自然语言处理、知识问答、智能客服、企业知识库和 AI 应用开发中非常重要的一个术语&#xff0c;全称是 Retrieval-Augmented Generation&#xff0c;通常翻译为“检索增强生成”。它用来描述一种让大语言模型先从外部资料中检索相关内容&#xff0c;再基于这…...

ChatGPT生成图表总“丑”?3步精准调优Prompt+4类D3.js/Plotly适配模板,即刻提升专业度

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ChatGPT数据可视化建议 在利用ChatGPT辅助数据分析与可视化时&#xff0c;关键在于将模型生成的结构化洞察高效映射到视觉表达层。ChatGPT本身不直接渲染图表&#xff0c;但可精准生成符合主流库&#…...

ICLR 2026小米AI 技术深度解读

注&#xff1a;小米最新的 AI 顶会成果实际入选了 ICLR 2026&#xff08;国际学习表征会议&#xff09;&#xff0c;推测您提到的 ICML 为会议名称的混淆&#xff0c;本文将基于小米此次入选的核心研究成果&#xff0c;以及配套的 MiMo-V2.5 系列技术&#xff0c;按您要求的五大…...