OpenSSL下ECDSA验签:DER与r||s格式转换与排查
1. 一次让我排查到凌晨的验签失败大概两年前有个对接项目把我折腾得够呛。对方系统返回的签名是一串64字节的二进制数据我按惯例丢给EVP_DigestVerify结果接口干脆利落地返回0验签失败。我看了眼错误队列提示“wrong signature length”。当时第一反应是对方把摘要算法搞错了或者公钥格式不对于是换了公钥、换了摘要、换了填充方式折腾了大半夜最后才意识到问题出在签名数据的编码格式上——对方给的是r || s的裸拼接格式而 OpenSSL 的 EVP 验签接口要求的是 DER 编码的 ASN.1 结构。ECDSA 验签这件事说复杂也复杂说简单也简单。复杂在于它牵扯到椭圆曲线、大数运算、ASN.1 编码简单在于真正动手时其实就是几个 API 来回调。但实际项目里恰恰是“签名数据的格式”这一环最容易被忽略因为 OpenSSL 的不同接口对签名数据的期望完全不一样有的收 DER有的收原始拼接用错就是静默失败连个像样的报错都不给。这个坑我后来在好几个项目里都见过所以干脆把 DER 格式的统一处理逻辑整理成文希望能帮你少走点弯路。这篇文章适合三类人一是刚接触 OpenSSL 和 ECDSA、正在对接验签功能的新手二是已经能跑通 demo、但在真实环境里遇到签名格式兼容问题的一线开发三是需要维护跨语言、跨平台签名互操作的老手。内容从 ECDSA 签名的本质讲起再拆解 DER 编码规则最后给完整的转换代码和排查经验争取让你看完之后能直接抄作业。2. ECDSA签名到底是什么一对整数和它的两种长相2.1 签名运算的本质ECDSA 签名本质上就是两个大整数通常记作(r, s)。签名过程的简化描述是先用随机数k与基点G做标量乘法得到临时点kG取它的 x 坐标模曲线阶n得到r再用消息摘要e、私钥d、随机数k和r计算s k^{-1}(e r*d) mod n。验签时拿着公钥Q、消息摘要e和这两个整数算一组点加和标量乘最后比较结果是否等于r变换后的值。所以从数学层面看签名只是一对整数r和s都在[1, n-1]区间内。但计算机世界里整数不能裸奔需要约定怎么存、怎么传。这个约定其实就是编码格式而 ECDSA 最常见的就是两种DER 编码和原始拼接编码r || s。DER 编码是 ASN.1 的一种规则OpenSSL 的 EVP 接口用它原始拼接编码就是按固定长度把r和s的字节串拼在一起很多硬件钱包、链上生态、嵌入式 SDK 习惯用它。同一个签名用两种方式表示长度完全不同字节内容也完全不同但验签时两者等价。2.2 DER编码为什么P-256的DER签名长度是不固定的DER 编码下的 ECDSA 签名是一个SEQUENCE里面包含两个INTEGER。结构用 ASN.1 语法表示就是ECDSA-Sig-Value :: SEQUENCE { r INTEGER, s INTEGER }这里有个特别容易踩坑的细节ASN.1 的INTEGER是有符号整数。当r或s的最高字节最高位为 1 时DER 编码必须在前面补一个0x00前缀否则解码端会把它当成负数。由于 P-256 的曲线阶n非常接近2^256r和s的 32 字节大数表示大概有一半概率最高位是 1所以 DER 编码后的签名长度通常是 70 到 72 字节而不是固定的 64 字节。这个“长度不固定”的特点在实际项目中非常致命。数据库字段定长 72 字节却偶尔截断、网络传输缓冲区按 64 字节分配导致溢出、日志里同一个用户的签名一会儿 70 字节一会儿 72 字节这些都是我实际见过的线上事故。理解了 DER 的补零规则你就知道这不是什么玄学纯粹是编码决定的。2.3 为什么不同系统返回的签名长相不一样跨系统对接时编码格式不一致是最常见的“隐形杀手”。不同语言、不同库对 ECDSA 签名的默认输出格式各不相同。场景签名输出格式说明OpenSSL EVP 接口DEREVP_DigestVerify期望的格式JavaSignature.sign()DERJCA 标准默认输出Goecdsa.SignASN1DER标准库提供 ASN.1 封装Goecdsa.Sign后自行拼接r很多钱包/链上 SDKr自定义网络协议自定义常见于私有加密协议这种割裂导致的后果是A 系统用 Java 签出的 DER 签名B 系统用 OpenSSL 验签时直接传原始字节发现验不过C 系统用 Go 拼接的r || s发给 D 系统D 系统用ECDSA_verify去验照样失败。我在项目里给这种问题起了个名字——“签名格式时区差异”两地都在用正确的时间但互相看到的却是完全不同的东西。要做“同一处理”第一步就是认清当前手里拿到的到底是哪种格式。3. OpenSSL验签接口的“两套世界观”3.1 EVP层接口签名数据必须是DEROpenSSL 1.1.0 之后主推 EVP 接口上层业务代码接触最多的就是EVP_DigestVerifyInit和EVP_DigestVerify。这套接口的验签流程是先用EVP_PKEY装载公钥然后初始化验证上下文指定摘要算法最终传入待验数据与签名数据。这里的关键点是EVP_DigestVerify的sig参数必须是一个完整的 DER 编码字节流。如果你手里是r || s拼接格式直接传进去OpenSSL 会按 DER 去解析大概率在第一步就失败。更有意思的是某些场景下 OpenSSL 可能不会明确告诉你“格式不对”而是返回一个泛泛的错误码这就让排查变得更加困难。我见过不少封装层代码把签名数据从 hex 解码后就直接丢给EVP_DigestVerify完全没有考虑来源系统的编码习惯。这种代码在自测环境里可能一直正常因为自测时签名和验签都是同一套 OpenSSL 生成格式天然一致一旦接入外部系统立刻翻车。所以项目里但凡涉及外部签名输入格式探测和归一化应该是一等公民而不是事后补丁。3.2 底层ECDSA接口ECDSA_do_verify和ECDSA_verify的微妙区别如果你在用旧代码或者维护老项目很可能接触到另外一组函数ECDSA_do_verify和ECDSA_verify。这两个函数名字接近但输入格式完全不同。ECDSA_do_verify的参数是一个ECDSA_SIG结构体指针内部持有r和s两个BIGNUM。它不解析 DER只负责数学验签。所以要调用它你必须先把签名解析成ECDSA_SIG对象。而ECDSA_verify则直接接收一个unsigned char*的签名缓冲区和长度内部会先调用d2i_ECDSA_SIG做 DER 解码再执行验签。换句话说ECDSA_verify其实跟 EVP 类似期望的是 DER。这就产生了一个非常常见的混淆老代码里有人用ECDSA_do_verify却把 DER 字节流直接强转成ECDSA_SIG*传入编译器不报错运行结果却一塌糊涂还有人反过来用ECDSA_verify却传入 64 字节的原始拼接同样静默失败。这类问题在代码评审里很难发现因为编译期完全看不出来。3.3 怎么判断当前场景需要哪种格式判断标准其实很简单看接口声明里签名参数的类型和语义。EVP_DigestVerify和ECDSA_verify接受的是字节流语义是“ASN.1 DER”ECDSA_do_verify接受的是ECDSA_SIG*语义是“已经解析好的整数对”。实际项目中我倾向于用一句话总结凡是传入二进制签名字节流的默认都按 DER凡是传入ECDSA_SIG结构体的内部才是原始整数。如果拿不准可以直接用d2i_ECDSA_SIG做一个试探性解析能解析成功就说明是 DER解析失败则可能是按原始拼接。这个思路在后面统一处理方案里会派上大用场。4. DER与原始格式的互转实操从原理到可抄代码4.1 构造DER从r || s到ASN.1的两种写法假设对方给了 64 字节的原始拼接前 32 字节是r后 32 字节是s我们需要把它转成 DER 才能走 EVP 验签。第一种写法是自己手动编码 ASN.1虽然麻烦但能帮你把 DER 规则吃透。手动编码的核心步骤是这样的取出r的 32 字节大端表示检查最高字节是否 0x80如果是则前面补一个0x00。对s做同样的处理。每个整数编码成0x02 || 长度 || 值的 TLV 结构。最后把两个 INTEGER 放入 SEQUENCE即0x30 || 总长度 || 内容。如果内容总长度小于 128 字节P-256 场景必然满足长度字段就是单字节如果超过 127 字节则需要用长格式0x81 || length。由于 ECDSA 签名内部只有两个 INTEGER整体长度无论如何不超过 150 字节长格式最多也就是0x81加一字节长度。实现代码大概长这样static int raw_to_der_manual(const unsigned char *raw, size_t raw_len, unsigned char *out, size_t *out_len) { size_t field raw_len / 2; const unsigned char *r raw; const unsigned char *s raw field; size_t r_off 0, s_off 0; unsigned char r_buf[128], s_buf[128]; // 处理r r_buf[r_off] 0x02; if (r[0] 0x80) { r_buf[r_off] field 1; r_buf[r_off] 0x00; memcpy(r_buf r_off, r, field); r_off field; } else { r_buf[r_off] field; memcpy(r_buf r_off, r, field); r_off field; } // 处理s s_buf[s_off] 0x02; if (s[0] 0x80) { s_buf[s_off] field 1; s_buf[s_off] 0x00; memcpy(s_buf s_off, s, field); s_off field; } else { s_buf[s_off] field; memcpy(s_buf s_off, s, field); s_off field; } size_t content_len r_off s_off; out[0] 0x30; out[1] (unsigned char)content_len; memcpy(out 2, r_buf, r_off); memcpy(out 2 r_off, s_buf, s_off); *out_len content_len 2; return 0; }这个实现只适用于content_len 128的情况P-256 完全满足P-384 也没问题P-521 的r、s各 66 字节加上补零最多 67 字节一个 INTEGER两个加在一起最多 136 字节结构头需要长格式上面代码就要微调。所以在生产环境我其实不建议手写除非你非常清楚边界条件。推荐的第二种写法是直接用 OpenSSL 的 API先用BN_bin2bn把r、s转成BIGNUM放到ECDSA_SIG里再调用i2d_ECDSA_SIG完成 DER 编码#include openssl/ec.h #include openssl/ecdsa.h #include openssl/bn.h #include openssl/err.h static int raw_to_der_openssl(const unsigned char *raw, size_t raw_len, unsigned char **der_out, int *der_len) { size_t field raw_len / 2; ECDSA_SIG *sig ECDSA_SIG_new(); if (!sig) return -1; BIGNUM *r BN_bin2bn(raw, (int)field, NULL); BIGNUM *s BN_bin2bn(raw field, (int)field, NULL); if (!r || !s) { BN_free(r); BN_free(s); ECDSA_SIG_free(sig); return -1; } // ECDSA_SIG_set0成功后sig接管r和s的所有权 if (ECDSA_SIG_set0(sig, r, s) ! 1) { BN_free(r); BN_free(s); ECDSA_SIG_free(sig); return -1; } *der_out NULL; *der_len i2d_ECDSA_SIG(sig, der_out); ECDSA_SIG_free(sig); if (*der_len 0) { return -1; } return 0; }用完后记得OPENSSL_free(*der_out)释放i2d分配的内存。这段代码有个关键点ECDSA_SIG_set0成功后r和s的所有权转移给sig不能再手动BN_free否则双重释放直接崩溃。4.2 解析DER从ASN.1到r || s反过来如果你从 Java 系统拿到的是 DER 签名但下游接口只需要 64 字节原始拼接就需要把 DER 解析成r || s。用 OpenSSL API 解析非常顺d2i_ECDSA_SIG一步到位然后ECDSA_SIG_get0取出r、s最后用BN_bn2binpad按固定宽度输出。BN_bn2binpad很关键它会把r、s都填充到指定字节长度避免出现r只有 31 字节时前面掉零。static int der_to_raw_openssl(const unsigned char *der, size_t der_len, unsigned char *raw, size_t raw_len) { const unsigned char *p der; ECDSA_SIG *sig d2i_ECDSA_SIG(NULL, p, (long)der_len); if (!sig) return -1; const BIGNUM *r NULL, *s NULL; ECDSA_SIG_get0(sig, r, s); size_t field raw_len / 2; if (BN_bn2binpad(r, raw, (int)field) ! (int)field) { ECDSA_SIG_free(sig); return -1; } if (BN_bn2binpad(s, raw field, (int)field) ! (int)field) { ECDSA_SIG_free(sig); return -1; } ECDSA_SIG_free(sig); return 0; }注意d2i_ECDSA_SIG的第二个参数是const unsigned char**它会移动指针指向“消费完”的位置。如果你传入的缓冲区后面还有其他数据p不会指向末尾你可以通过der_len - (p - der)来判断是否有残留字节。如果残留字节非零说明传入的数据可能混入了额外内容这种签名在严格模式下一律应当拒绝。4.3 用OpenSSL命令行交叉验证转换结果代码写完了怎么确认转换对不对我最常用的手段是 OpenSSL 命令行交叉验证快速、直观还不容易有逻辑盲区。首先用 OpenSSL 生成一对测试密钥并签出 DER 格式的签名文件# 生成P-256私钥 openssl ecparam -name prime256v1 -genkey -noout -out ec_private.pem # 导出公钥 openssl ec -in ec_private.pem -pubout -out ec_public.pem # 对待签名数据做摘要并签名输出DER格式 openssl dgst -sha256 -sign ec_private.pem -out sig.der data.bin然后用asn1parse查看 DER 内部结构确认r、s的编码形式和补零情况openssl asn1parse -in sig.der -inform DER输出大致长这样0:d0 hl2 l 70 cons: SEQUENCE 2:d1 hl2 l 33 prim: INTEGER :A1B2C3... 37:d1 hl2 l 33 prim: INTEGER :D4E5F6...注意看 INTEGER 的长度如果第 2 行显示l33说明这个整数最高位字节 0x80补了一个0x00如果显示l32说明没有补零。两种都是合法 DER但转换成原始拼接时要统一去掉补零。验证签名是否正确用dgst -verifyopenssl dgst -sha256 -verify ec_public.pem -signature sig.der data.bin如果你手里只有r || s的 raw 格式想快速验证它对应的 DER 结果可以先手工构造一个 DER 文件用前面代码生成或者写个小工具输出到文件再跑dgst -verify。这个流程我几乎每次对接外部系统都会跑一遍确保转换逻辑没有系统性偏差。5. 项目里的统一处理把格式归一化落在代码里5.1 设计思路入口统一、探测先行、出口归一前面说的都是底层 API 的差异实际项目中更重要的是一套可持续的统一处理策略。我坚持的原则是无论业务系统从哪里拿到签名内部一律先归一化成 DER再走 EVP 验签。这个策略的好处是业务层只依赖一个验签入口不关心来源系统是 Java、Go、钱包还是嵌入式设备。归一化流程可以拆成三步探测签名格式。根据长度和首字节判断是 DER 还是 raw。转换。raw 转 DER或者 DER 原样保留。统一走EVP_DigestVerify验签。探测逻辑不能只靠长度因为某些情况下 raw 长度和 DER 长度会撞车。最可靠的方法是看首字节DER 签名一定以0x30开头SEQUENCE 标签raw 签名则没有任何固定的首字节约束。如果首字节是0x30进一步用d2i_ECDSA_SIG尝试解析解析成功且消费长度与输入长度一致才能确认是 DER。5.2 一个可供直接使用的归一化验签函数下面这段代码是我在项目里实际用过的简化版覆盖 raw 和 DER 两种输入统一走 EVP 验签#include openssl/evp.h #include openssl/ec.h #include openssl/ecdsa.h #include openssl/pem.h #include openssl/bn.h #include openssl/err.h static int verify_with_unified_sig(EVP_PKEY *pkey, const unsigned char *msg, size_t msg_len, const unsigned char *sig, size_t sig_len) { const unsigned char *der_sig sig; unsigned char *der_buf NULL; int der_len (int)sig_len; int ret 0; // 探测首字节是0x30且能解析为ECDSA_SIG则视为DER if (sig_len 0 sig[0] 0x30) { const unsigned char *p sig; ECDSA_SIG *probe d2i_ECDSA_SIG(NULL, p, (long)sig_len); if (probe) { ECDSA_SIG_free(probe); der_sig sig; } else { // 虽然首字节是0x30但解析失败按raw处理 if (raw_to_der_openssl(sig, sig_len, der_buf, der_len) ! 0) { return 0; } der_sig der_buf; } } else { // 首字节不是0x30按raw处理 if (raw_to_der_openssl(sig, sig_len, der_buf, der_len) ! 0) { return 0; } der_sig der_buf; } EVP_MD_CTX *ctx EVP_MD_CTX_new(); if (!ctx) goto done; if (EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, pkey) ! 1) goto done; if (EVP_DigestVerify(ctx, der_sig, (size_t)der_len, msg, msg_len) ! 1) goto done; ret 1; done: if (der_buf) OPENSSL_free(der_buf); if (ctx) EVP_MD_CTX_free(ctx); return ret; }这个函数有几个细节值得注意。第一EVP_DigestVerifyInit里指定的摘要算法必须和签名方一致否则验签必然失败。有的场景里签名方是对原始数据先做摘要再签名这时验签要改用EVP_DigestVerifyInitEVP_DigestVerifyUpdate传原始数据而不能自己再包一层哈希。第二探测 DER 时我用d2i_ECDSA_SIG解析确认而不只是看首字节能有效规避数据撞车。某些 raw 签名恰好以0x30开头概率不高但真实环境出现过必须用完整解析来兜底。第三raw_to_der_openssl内部使用ECDSA_SIG_set0之后所有权转移不能在失败路径外再BN_free。5.3 按曲线字节数对齐P-256、P-384、P-521的raw长度陷阱raw 格式的r || s每个整数按“曲线字节数对齐”输出。这里的曲线字节数不是简单的位宽除以 8而是要向上取整。P-256 是 32 字节P-384 是 48 字节P-521 则是 66 字节因为 521 位除以 8 是 65.125向上取整到 66。这个陷阱在实际对接中出现过很多次。有人写死了 64 字节接 P-384 时直接内存越界有人按 65 字节处理 P-521结果验签永远失败。所以在统一处理函数里raw 长度必须由曲线的字节数推导而不是拍脑袋定。推导方式可以这么写size_t curve_field_bytes(const EC_KEY *key) { const EC_GROUP *group EC_KEY_get0_group(key); int bits EC_GROUP_get_degree(group); return (size_t)((bits 7) / 8); }注意(bits 7) / 8是向上取整的标准写法521 位会得到 66 字节。如果你用EVP_PKEY而非EC_KEY可以通过EVP_PKEY_get_utf8_string_param拿到曲线名再映射字节数或者直接用EVP_PKEY_get_bn_param配合组参数获取阶的长度。无论哪种方式核心思想是raw 格式的长度由曲线决定不能假设任何固定值。6. 常见问题与排查技巧实录6.1 一张能救命的问题速查表我把这些年遇到的验签问题整理成一张速查表排查验签失败时按表逐项核对能省下大量时间。现象大概率原因排查方向EVP_DigestVerify返回0错误为wrong signature length传入的是raw拼接而非DER先转DER再验签d2i_ECDSA_SIG解析失败数据被截断、混入额外字节、DER结构损坏用asn1parse看结构Java签名到OpenSSL验签失败Java的Signature输出是DER但业务层可能做了额外hex/base64转换导致字节不一致确认签名数据的字节流转形式Goecdsa.Sign拼接的raw验签失败raw转DER时没有做补零判断检查转码函数是否处理了0x80前缀验签偶尔失败概率约为50%手写DER编码时漏掉了整数补零逻辑检查整数最高位判断P-521签名长度一直是132但验签失败raw长度应按曲线66字节对齐不是65用EC_GROUP_get_degree推导同一个签名不同系统验签结果不一致S值低位归一化low-S问题确认是否对s做了归一化处理6.2 现场一raw签名被当成DER解析某个系统从一个硬件模块拿签名模块输出的就是 64 字节 raw。开发同学很自然地调EVP_DigestVerify验签失败后开始怀疑公钥、摘要、字节序甚至怀疑硬件模块坏了。后来我把签名文件拉下来用asn1parse看了一眼直接就是乱码根本不是一个合法的 ASN.1 结构。改用i2d_ECDSA_SIG把 raw 转成 DER 后一次通过。这个案例教训比较典型验签失败的排查起点永远是“签名数据到底是什么格式”而不是“我的算法配置对不对”。格式错了后续一切检查都是白搭。6.3 现场二DER里的补零字节被当成r的一部分另一个项目里对方把 DER 签名转成 raw 后回传但我们接到的r是 33 字节s是 33 字节原因是在解析 DER 时没有处理0x00前缀直接把整个 INTEGER 的 value 字段原封不动拼接进去了。BN_bn2binpad本来能自动去掉前导零并补齐到指定宽度但对方是手写解析漏了这一步。类似问题用asn1parse一查就露馅INTEGER 的 value 长度是 33说明最高位字节 0x80需要补零位。正确的做法是解析 DER 时拿到BIGNUM后一律用BN_bn2binpad(r, out, field_len)输出而不是手动memcpy。这样无论 DER 里有没有补零输出永远是统一的曲线字节长度。6.4 现场三P-521的66字节raw坑P-521 的 raw 长度问题值得单独记录。一次对接 P-521 时对方文档写“r和s各65字节”我们据此分配缓冲区并填充结果验签偶发失败。后来排查发现521 位大数按大端表示需要 66 字节因为最高字节只用到了低 9 位前 7 位恒为 0所以合法的r、s在某些实现里会被写成 65 字节丢掉最高位的 0。但 OpenSSL 的BN_bn2binpad要求固定 66 字节直接拿 65 字节的数据去BN_bin2bn大数数值本身没错但字节序对齐和后续填充逻辑就会出问题。解决方式是对输入 raw 先做长度归一化如果长度是 65前面补一个0x00变成 66如果已经是 66直接使用。这个细节不写进处理函数线上早晚要出幺蛾子。6.5 避坑技巧S值的低位归一化还有一个容易忽略的隐蔽问题叫 low-S 归一化。ECDSA 中如果(r, s)是一个合法签名那么(r, n - s)同样是合法签名验签方程式完全成立。某些生态出于安全考虑要求s n/2或者规定接收方必须拒绝 high-S 签名。如果你从外部拿到一个 DER 签名其内部s已经被做了一次 low-S 归一化而对比的基准数据用的是原始s那你转换出来的 raw 就和预期不符。实践中我在统一处理函数里通常会假设签名方不会故意变更s但遇到对比两套系统签名结果是否一致的需求时会额外检查 low-S 情况。这一点不需要每次验签都做但排查疑难杂症时是个值得留意的方向。在最终代码中我还加了一个小技巧i2d_ECDSA_SIG之后用d2i_ECDSA_SIG做一次回读比对两次结果中的r、s是否一致。这样能确保编码函数没有歧义对于自研编码器尤其重要。OpenSSL 提供的编码器通常很可靠但如果你为了兼容某个老系统而手写了 DER 生成逻辑双向往返测试是避免隐蔽不一致的最简单手段。我在实际项目里把格式归一化做成了公共函数库之后所有对接验签的服务都收敛到同一个入口。后续遇到再多“对方的签名格式不一样”的问题只需要在入口处的探测逻辑里加一种格式分支业务层完全无感。这种做法的收益会随着接入的系统数量增加被放大建议你在设计初期就考虑进去。

相关新闻

线性代数第五章核心:特征值、特征向量与相似矩阵的本质理解

线性代数第五章核心:特征值、特征向量与相似矩阵的本质理解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 1:02:32 阅读更多 →
基于MP2642GR-Z与PIC18F86J15的2S电池主动均衡模块设计

基于MP2642GR-Z与PIC18F86J15的2S电池主动均衡模块设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 1:02:32 阅读更多 →
单层开槽贴片天线实现滤波与辐射一体化设计

单层开槽贴片天线实现滤波与辐射一体化设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 1:01:32 阅读更多 →

最新新闻

linear-cli 模板工作流揭秘:--template 预填字段,issue 与 project 创建效率翻倍

linear-cli 模板工作流揭秘:--template 预填字段,issue 与 project 创建效率翻倍

【免费下载链接】linear-cli linear without leaving the command line: list, start, and create PRs for linear issues. agent friendly. 项目地址: https://gitcode.com/gh_mirrors/lin/linear-cli 点击查看 免费下载 linear-cli 是一个让 Linear 用户不用离开…

2026/10/16 1:52:43 阅读更多 →
ERPNext 免费快速上手指南:如何用开源 ERP 管好账、管好库存

ERPNext 免费快速上手指南:如何用开源 ERP 管好账、管好库存

ERPNext 免费快速上手指南:如何用开源 ERP 管好账、管好库存 【免费下载链接】erpnext Free and Open Source Enterprise Resource Planning (ERP) 项目地址: https://gitcode.com/GitHub_Trending/er/erpnext ERPNext 是一款完全免费的开源 ERP 系统&#x…

2026/10/16 1:52:43 阅读更多 →
AI帮我搞定一套完整版农村村务管理系统(FastAdmin+小程序)

AI帮我搞定一套完整版农村村务管理系统(FastAdmin+小程序)

前言 最近接了一个农村村务管理系统的项目需求,也可以说是非常经典的政务/乡村数字化项目。 传统的村务管理一直存在这些痛点: ✅ 村务、财务全部纸质台账,杂乱易丢、无法溯源 ✅ 村民办事只能线下跑,流程不透明、审批慢 ✅ 村集体…

2026/10/16 1:52:43 阅读更多 →
仓颉 ArkUI ListItemGroup 分组列表组件完全指南:从 API 详解到吸顶吸底实战

仓颉 ArkUI ListItemGroup 分组列表组件完全指南:从 API 详解到吸顶吸底实战

文档知识库教程OpenHarmony 【免费下载链接】CangjieCorpus 本仓库为仓颉编程语言语料库,聚焦 仓颉编程语言 核心知识体系,整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源,经结构化处理与专业标注,构建为支持 R…

2026/10/16 1:52:43 阅读更多 →
Buzz 离线语音转文字完整指南:从录音到可编辑字幕只需 3 步

Buzz 离线语音转文字完整指南:从录音到可编辑字幕只需 3 步

Buzz 离线语音转文字完整指南:从录音到可编辑字幕只需 3 步 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz 两小时…

2026/10/16 1:52:43 阅读更多 →
GLSL 精度限定符 lowp 完全指南:The Book of Shaders 中的精度体系与实践

GLSL 精度限定符 lowp 完全指南:The Book of Shaders 中的精度体系与实践

【免费下载链接】thebookofshaders Step-by-step guide through the abstract and complex universe of Fragment Shaders. 项目地址: https://gitcode.com/gh_mirrors/th/thebookofshaders 点击查看 免费下载 导读 lowp 是 GLSL ES(嵌入式系统着色语言…

2026/10/16 1:51:43 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →