Coppersmith攻击实战:已知p高位比特分解RSA模数
假设你手里有一份泄露出来的日志片段上面只有几行十六进制字符串其中一行恰好是某个RSA公钥的模数n另一行则是p的前半段比特。看起来好像没什么用——毕竟只知道一半剩下的512位不还是要跑穷举但如果你懂Coppersmith攻击就会知道“已知p的高比特位”恰恰是一个经典且高效的分解n场景。这篇文章就把这个场景从原理到代码完整拆开覆盖“为什么能分解”“边界在哪里”“SageMath里怎么落地”“实际使用中有哪些坑”。无论你是做密码学竞赛、安全研究还是单纯想理解RSA在部分信息泄露下有多脆弱这篇都值得读完再动手跑一遍。1. 攻击场景从哪来p的高位比特为什么会泄露先说结论这不是凭空想象出来的攻击模型而是现实中反复出现过的泄露路径。很多人一听到“已知p的高位比特”就觉得只存在于竞赛题里实际上密钥生成的熵缺陷、随机数预测、侧信道采集、甚至硬件设计上的偷懒都可能把p的部分比特送到攻击者手上。1.1 随机数生成器的熵不足与共享素数最典型的场景是嵌入式设备。某些设备的随机数生成器由于硬件熵源设计不佳导致每次开机生成的素数p都共享一段很高的公共前缀。比如某批设备生成的RSA密钥中p的高32位或高64位固定不变。这种情况下如果你拿到两台设备的公钥n1、n2并且知道它们都来自同一批生成批次那你很可能只需要对其中一台尝试“已知固定高位”的分解或者更粗暴地直接gcd(n1, n2)撞共享因子。但如果只有一台设备的n而那台设备的随机数恰好差到把p的高位写成固定值那么“已知高位分解n”就直接适用了。1.2 侧信道泄漏与内存拷贝残留第二个常见来源是侧信道。密码学实现中的模幂运算、素数生成过程都可能通过功耗、电磁辐射或者时间特征泄漏出部分中间值的比特。特别是当目标设备没有做常数时间处理或者素数生成代码里提前退出的条件判断依赖了p的具体取值攻击者通过多次采样可以恢复出p的高位部分比特。这类信息往往不完整、有噪声但哪怕只知道其中一部分连续的高位比特也足以进入Coppersmith的攻击窗口。1.3 竞赛题与测试环境里的经典考法第三个场景就是各类密码学竞赛和内部安全培训了。几乎每年都会出现“已知p高位”的题目给你一个1024位的n再给你p的高位十六进制片段比如只给了前256比特或前320比特然后让你分解n。这类题目的本质完全一致只是把“高位比特”包装成一段残缺的p。许多人卡住的原因不是不知道RSA而是不知道一旦p的部分比特泄露分解问题就退化成了一个可计算的小根问题。还有更贴近工程的情况某些程序把密钥写进日志用于调试但日志只打印了p的前几位或者内存镜像抓取后页面中残留了部分p的值但被截断。这些案例在实际测试中我都遇到过。所以“已知高比特位p分解n”并不是一个冷门绝招而是每一个做密钥安全评估的人都该掌握的基本功。2. 数学内核把“分解n”变成“求小整数根”为什么知道p的高位比特就能分解n表面上看未知的低位比特数量仍然巨大暴力枚举根本不可行。但Copper-smith攻击的核心思路是把问题转化成一个关于“未知小整数”的模方程再用格基约减把这个小整数捞出来。2.1 建立方程未知量是低位的x设n p × q且p、q都是大约512比特的素数以1024比特的n为例。假设我们已经知道p的高位部分不知道的是p的低位x。把p写成p p_high x其中p_high是已知的高位部分对应的整数值x满足 0 ≤ x 2^kk是未知低位的比特数。如果p_high是你从泄露片段里恢复的高位真值那么x就是低位的未知偏移。这里要特别注意“高位的真值”和“高位片段的数值”区别后面实操部分我会专门讲。现在先假设p_high已经是把未知低位补零之后的那个数。接着看模p的方程p_high x ≡ 0 (mod p)也就是说x是多项式f(x) p_high x模p的一个根。问题变成已知一个整数多项式f它在一个未知的因子pp整除n但我们不知道p上有一个小根x如何求出x如果模数是p本身直接遍历x或者用普通求根方法就行但问题在于p未知。好在Coppersmith给出了一个强有力的定理不需要知道p只需要知道p是n的某个因子并且因子大到一定程度就可以在多项式时间内找到这个小根。2.2 Coppersmith定理与小根判据Coppersmith定理的一个常用形式如下设n是整数b是n的一个因子且b ≥ n^β。设f(x)是次数为d的首一整数多项式。如果f有一个模b的根x0并且满足|x0| ≤ n^(β²/d - ε)其中ε 0是任意小正数那么x0可以在多项式时间内被求出。放到我们的场景d 1β 0.5等长RSA因子于是根的上界大约是n^(0.25 - ε)。对1024比特的n来说就是约2^(256 - 256ε)。也就是说只要未知低位比特数k小于256左右理论上就有希望恢复出x从而得到完整的p。注意这里的解码逻辑p本身的比特数约为512未知低位比特数必须小于p比特数的一半。换个说法已知的高位比特数必须大于p比特数的一半。如果n是1024比特p是512比特那至少要知道p的高256比特以上才能稳定分解。如果只泄露了p的高16位或32位那离这个窗口还差得远单靠这个手段就不够了。2.3 Howgrave-Graham与LLL在背后做了什么很多人看到small_roots一行代码就完事了根本不知道内部发生了什么。为了让后续调参时不抓瞎我简单讲一下它背后的两个关键点。Howgrave-Graham给出了一个实用判据如果能构造一个多项式g(x)满足g(x0) ≡ 0 (mod p^k)即根x0仍然是g模p幂次的根关于g(xX)系数的欧几里得范数足够小使得小根可以通过整数上的浮点求根直接恢复那么x0就能被可靠地找出来。Coppersmith的构造方法就是生成一族多项式f(x)^j, x·f(x)^j, x²·f(x)^j, ...把它们在x X处缩放后放进一个格lattice再对格做LLL约减期望得到满足Howgrave-Graham条件的短多项式。LLL的全称是Lenstra–Lenstra–Lovász它能在格中找到一组近似最短的向量。整个攻击之所以可行本质上是把“找小根”变成了“在格中找短向量”而LLL正是干这个的。理解这一层你就能明白为什么small_roots有时会卡死或成功不了格维数太大LLL约减的时间会指数上升参数设置不对短向量里找不到符合条件的多项式自然也就求不出根。所以并不是无脑调用就一定成功后面我会专门讲参数怎么调。3. 分步实操SageMath中完成已知高比特位分解n理论说再多不如跑一遍。我推荐直接在SageMath环境里做因为它内置了大整数、多项式环和small_roots方法几乎不需要自己实现格攻击。本地没装的话用SageMath官方在线环境也可以跑通下面的示例。3.1 准备一个可复现的实验场景先自己生成一个RSA场景来验证整套流程。为了让结果可控我们构造一个1024比特的np、q等都是512比特的素数。然后模拟“已知p的高256比特”的情形。from sage.all import * # 生成一个 1024 比特的 RSA 模数 bits 512 p random_prime(2^bits, lbound2^(bits-1)) q random_prime(2^bits, lbound2^(bits-1)) n p * q # 模拟已知 p 的高 256 比特 known_bits 256 unknown_bits bits - known_bits # 256 # p_high_raw 是高位部分的数值 p_high_raw p unknown_bits # p_high 是把未知低位补零后的完整整数 p_high p_high_raw unknown_bits print(n , n) print(p_high , p_high) print(unknown_bits , unknown_bits)实际攻击时你手里不会同时有p只会拿到n和p_high。这里生成p只是为了验证攻击结果是否正确。3.2 构造多项式环并求解小根接下来是核心调用。在SageMath中small_roots方法实际上定义在模n的多项式环上。我们用Zmod(n)构造多项式环令f(x) p_high x再传入X 2^unknown_bits作为未知量的上界。# 在模 n 的多项式环上定义 f(x) ZmodN Zmod(n) P.x PolynomialRing(ZmodN) f p_high x # x 的取值范围是 [0, 2^unknown_bits) X 2^unknown_bits # beta0.5 表示 p 大约是 n 的平方根量级 # epsilon 越小理论边界越宽松但计算越慢 roots f.small_roots(XX, beta0.5, epsilon0.02) if roots: x0 ZZ(roots[0]) p_recovered p_high x0 print(recovered p , p_recovered) print(p matches:, p_recovered p) q_recovered n // p_recovered print(recovered q , q_recovered) print(n p*q:, p_recovered * q_recovered n) else: print(no root found)这段代码跑通之后你会看到p被完整恢复n也被成功分解。整个流程在SageMath里只有不到二十行真正有价值的反而是理解哪些参数能改、哪些不能乱改。3.3 从十六进制泄露片段构造p_high实际场景里泄露的往往是一段十六进制字符串而不是一个整数。假设你知道p的高64位十六进制值为某个片段要拼成p_high就需要做一次移位换算。比如p是512比特已知高256比特十六进制字符串长度就是64个字符因为256比特对应64个十六进制字符。hex_high abcd1234...f00d # 64 个十六进制字符正好 256 比特 known_high_int int(hex_high, 16) # 512 - 256 256所以左移 256 位 p_high known_high_int 256注意这里的known_high_int并不是p_high本身而是p的高位数值。把它左移unknown_bits位后才得到低位全为零的p_high。如果你在代码里漏掉左移方程变成known_high_int x p那x的范围就完全不对攻击必然失败。3.4 验证和常见预期对1024比特的n、512比特的p当unknown_bits 256时理论边界刚好卡在n^0.25附近实际运行small_roots大概率成功耗时通常在几秒到几十秒之间。如果unknown_bits减少到240运行会非常快如果增加到260就超出了理论边界直接跑大概率无解需要减小epsilon并承受更长的运算时间。为什么说“大概率”因为Coppersmith攻击的边界含有epsilon项而epsilon的取值会影响格维数和实际成功概率。下面一节专门讲这个平衡问题。4. 参数与边界unknown_bits、epsilon、格维数之间的权衡small_roots不是黑魔法它的几个参数直接决定了攻击能不能成功、以及要等多久。我在调参上踩过不少次这里总结一套可参考的经验。4.1 理论边界到底怎么算对于d1、beta0.5理论可解条件为X n^(0.25 - ε)用比特数表达就是unknown_bits log2(n) / 4。以n为1024比特为例log2(n)/4 256。所以unknown_bits 256在ε趋近于0时可以算ε一旦变大边界反而收缩到255甚至更小。这解释了为什么临界状态下调小epsilon能提高成功率。如果你的n不是等长因子比如p只有256比特而n有1024比特也就是说q为768比特那么beta 0.25理论边界变成n^(0.0625 - ε)换算成比特只有64位左右。这意味着当两个因子严重不平衡时已知高位攻击的效果会大幅下降。所以不要在任何情况下都套beta0.5。4.2 epsilon怎么选边界与速度的取舍epsilon的语义有点反直觉epsilon越大理论边界越紧但LLL的格维数可以选得小所以算得快epsilon越小理论边界越松但算法必须拉高格维数才能保证找到短向量所以算得慢还容易爆内存。实际操作中我一般这样选择unknown_bits比理论边界小10比特以上直接用默认epsilon秒出。unknown_bits贴近理论边界比如差2-5比特把epsilon设到0.01或0.005耐心等。unknown_bits超出理论边界先别急着调参要么去收集更多信息位要么换其他攻击手段。4.3 不同unknown_bits下的实测表现为方便对比我整理了一份在我本机虚拟机环境下的实测数据。环境是SageMath 9.x内存8GBn为1024比特p和q等长。需要说明的是每个人的配置和Sage版本不同耗时会有波动但趋势是一致的。unknown_bits理论边界epsilon耗时结果200256默认约2秒成功240256默认约5秒成功2502560.05约20秒成功2542560.05约1分钟成功2562560.02约3分钟大概率成功2582560.01长时间运行成功率低不建议看到这里你应该明白了理论边界只是门槛不是绝对的“超过就完全不可能”。算法内部通过调整格维数可以逼近边界但代价是计算资源。所以实战中如果条件允许优先确保已知高位比特比p比特数的一半多出至少10比特这样又快又稳。4.4 已知比特不够时怎么办如果手里已知的高位比特不足一半Coppersmith直接分解会非常吃力。这时有几种拓展思路收集其他形式的泄漏如果同时拿到了p的低位信息或者拿到了d的部分比特可以组合进同一套格构造里常见手法是把低位移到方程另一边构造p_low x·2^k的变体。利用多次签名的部分信息某些场景下同一私钥的不同签名可能泄漏出不同的随机中间比特组合起来填充已知比特。换攻击面尝试小公钥指数攻击、共享因子检测、Fermat分解等。高位不足时先看看n的两个因子是否离得太近或者公钥指数是否过小。5. 实战避坑我踩过的几个典型错误代码短不代表不会翻车。以下五个问题我都在实际运行里遇到过任何一个不注意都会让你在“为什么没解出来”上浪费大把时间。5.1 p_high忘了左移导致方程完全不对这是最高频的错误。泄露的十六进制片段是p的高位数值不是p补齐后的真值。如果你直接f known_high_int x那么当x取到低位部分时整个known_high_int x最多只是2^256量级而p是2^511量级相差天壤地别。正确做法一定是用known_high_int unknown_bits构造p_high。我在最开始学这个攻击时就因为漏了左移卡了整整一下午。5.2 多项式环选错ZZ上没有small_roots方法SageMath中small_roots方法定义在模复合数n的环上而不在普通整数环ZZ上。如果你写成P.x PolynomialRing(ZZ)再调f.small_roots()会直接报错AttributeError。正确的写法是PolynomialRing(Zmod(n))。这一点官方文档写得不显眼但几乎所有入门者都会踩。5.3 X设得太随意导致格维数失控X应该是2^unknown_bits也就是未知低位可能取到的最大值或者稍微加1。有些教程里会建议设置X时留一点余量比如X 2^unknown_bits 1这没问题。但如果你误把X设成2^512甚至2^1024LLL要处理的格会巨大内存直接爆掉。记住X代表的是未知量的上界不是整个p的上界。5.4 beta值用错导致解不出来如果p和q是等长的beta0.5没问题。但有些RSA实现会故意让两个因子长度相差很大比如用256比特的p配合768比特的q生成1024比特的n。这种时候你还写beta0.5程序的假设就错了。判断方法很简单先估算n的比特数再根据已知p的大致量级填beta。如果你完全不知道p的量级可以通过n分解出的因子长度频率来推测或者在代码里多试几个beta值。5.5 临界比特时失败误以为攻击无效有时候unknown_bits恰好卡在理论边界附近small_roots第一次跑没出结果不代表攻击不可行。我建议按顺序尝试确认p_high构造正确一格格缩小epsilon0.05、0.02、0.01、0.005如果还不行检查X是不是稍带余量最后再确认beta是否和因子量级匹配。只要你的未知比特数没有大幅超出理论边界这四步走完多半能出结果。最怕的是拿到一个临界题以为无解就放弃实际上只是epsilon没调够。6. 从分解到防御这一攻击给密钥生成敲的警钟懂得怎么攻自然也得知道怎么防。已知高位比特分解n之所以能成立根本原因是Coppersmith把“部分信息”放大成了“完全恢复”。也就是说RSA的安全性并不只是依赖因子分解的困难性还依赖素数生成过程的随机性不被破坏。6.1 生成密钥时不要人为固定任何比特有些硬件为了加速除法会约定p和q的高16位或高32位为某个常数。这种优化等于主动送给攻击者已知高位。一旦已知比特数超过因子长度的一半整个密钥基本就废了。所以密钥生成代码里p和q的每一位都应该来自高质量的随机源。6.2 随机数生成器的健康检查很重要熵源失效是很多真实泄露事件的根源。生成素数前至少要做一次随机数质量自检如果检测到连续多个采样值高度相关应该直接拒绝生成密钥。工程上还可以通过对比同一批次生成的多个公钥是否存在共享素数来反查随机源问题。6.3 侧信道防护不只在签名阶段很多人只关心模幂运算是否常数时间却忘了素数生成阶段的判断分支也会泄漏信息。实现RSA密钥生成时分支条件、提前退出逻辑也要尽量做到与数据无关。实在做不到就确保生成过程在可信环境内完成避免低频侧信道采样拿到高位比特。这些防御点看起来朴素但在实际设备评估中我见过太多因为“图省事”而留下高位固定或随机源劣化问题的案例。理解已知高位分解n不是为了在黑产里增加一种武器而是让你在审查密钥系统时能一眼看出哪些优化是危险的、哪些随机数实现是不合格的。

相关新闻

有道翻译API接入实战:从签名到批量翻译的完整指南

有道翻译API接入实战:从签名到批量翻译的完整指南

1. 从零上手有道翻译API:一个后端开发者的接入实录翻译能力几乎是现代应用开发的标配需求。无论是做跨境电商的商品描述本地化、做在线教育平台的课件多语言适配,还是做一个简单的浏览器插件帮用户快速看懂外文资料,背后都绕不开一个稳定可靠…

2026/10/17 22:25:25 阅读更多 →
AI赋能企业变革:人才先行落地路径与避坑指南

AI赋能企业变革:人才先行落地路径与避坑指南

简介:一份关于2025年AI赋能企业变革与人才先行的专题PDF,面向企业管理层、HR专家、部门经理及一线骨干,解决AI转型中“技术易得、人才难配”的核心痛点。内容引用麦肯锡预测,到2030年AI将为中国关键产业创造超6000亿美元价值&…

2026/10/17 22:24:24 阅读更多 →
InternVL3-14B-Pretrained多模态大模型预训练权重入门指南:ViT-MLP-LLM架构它能做什么、怎么开始

InternVL3-14B-Pretrained多模态大模型预训练权重入门指南:ViT-MLP-LLM架构它能做什么、怎么开始

【免费下载链接】InternVL3-14B-Pretrained 项目地址: https://ai.gitcode.com/OpenGVLab/InternVL3-14B-Pretrained 点击查看 免费下载 InternVL3-14B-Pretrained 是 OpenGVLab 开源的 InternVL3 系列 14B 多模态大模型的预训练(Pretrained&#xff09…

2026/10/17 22:23:24 阅读更多 →

最新新闻

查找算法全解析:从顺序查找到B+树,工程选型与避坑指南

查找算法全解析:从顺序查找到B+树,工程选型与避坑指南

很多人在学数据结构的时候,会把"查找"这一章当成一堆零散算法的集合:顺序查找、折半查找、哈希、二叉排序树……背完ASL公式就扔到一边。但我在实际做开发之后回头看,这一章恰恰是全书最容易和工程经验挂钩的地方——你写的每一条S…

2026/10/17 23:17:11 阅读更多 →
Claude Code(22):用 mcp-builder 构建自定义 MCP Server 的完整配置与验证

Claude Code(22):用 mcp-builder 构建自定义 MCP Server 的完整配置与验证

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

2026/10/17 23:17:11 阅读更多 →
SAP MTO配置核心:物料主数据四字段与特殊库存E的硬性约束

SAP MTO配置核心:物料主数据四字段与特殊库存E的硬性约束

简介:本资源是一份面向SAP顾问、制造企业计划与生产管理人员的MTO(按订单生产)业务全流程实操指南,聚焦机械、电子等定制化程度高行业的SAP系统落地难点。内容覆盖物料主数据配置(含MRP策略组20与个体/集中需求标识&am…

2026/10/17 23:16:10 阅读更多 →
R-AUC与T-AUC一文读懂:Qwen3.5-4B-singprobe流式安全指标与幻觉检测原理

R-AUC与T-AUC一文读懂:Qwen3.5-4B-singprobe流式安全指标与幻觉检测原理

【免费下载链接】Qwen3.5-4B-singprobe 项目地址: https://ai.gitcode.com/hf_mirrors/inclusionAI/Qwen3.5-4B-singprobe 点击查看 免费下载 Qwen3.5-4B-singprobe 是一个构建在 Qwen/Qwen3.5-4B 之上的流式安全护栏(streaming guardrail)探…

2026/10/17 23:16:10 阅读更多 →
从工具调用到具身执行:AI-Agent如何驱动机械臂完成物理任务

从工具调用到具身执行:AI-Agent如何驱动机械臂完成物理任务

上周在实验室里盯着一台六轴机械臂反复尝试把一颗M3螺丝插进工件孔里,旁边屏幕上的Agent日志一行行刷着“抓取失败、重试”“角度偏移0.8度、补偿”。那一刻我突然意识到,AI-Agent这一脚跨得比很多人想象的要大——短短两年前,我们还在为Agen…

2026/10/17 23:15:09 阅读更多 →
C语言qsort深度解析:从函数原型到比较函数避坑指南

C语言qsort深度解析:从函数原型到比较函数避坑指南

简介:这份PDF资料聚焦C语言标准库中qsort函数的实际用法,面向正在学习C语言、需要掌握通用排序技巧的初学者与进阶开发者,帮助解决不同数据类型排序时比较函数如何编写的问题。资源包共1个PDF文件,大小约32KB,内容以代…

2026/10/17 23:15:09 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 21:54:38 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →