首页/新闻资讯/正文详情

私钥碰撞源码揭秘:区块链钱包安全与数学概率的绝望

发布时间:2026/9/25 1:49:25 来源:云帆数科 栏目:资讯中心
私钥碰撞源码揭秘:区块链钱包安全与数学概率的绝望
简介面向区块链技术与密码学爱好者这份源码包聚焦ETH私钥碰撞主题包含完整C工程与Python辅助脚本可供学习区块链地址生成、私钥与Hash160推导等底层原理。压缩包共119个文件总大小8.55MB以C头文件25个.h、实现21个.cpp及编译中间文件为主同时提供6个Python脚本、CUDA源文件与可执行程序便于在Windows环境下直接查看工程结构和运行效果。已有3305人学习下载。资源内置地址库、Hash160数据文件及GPU引擎相关代码能帮助读者理解大规模地址扫描的设计思路工程中的.vcxproj、.sln等文件完整保留还原了从源码到构建的脉络。需特别说明此类内容仅用于学术研究与安全测试请勿用于非法活动。1. 私钥碰撞源码为什么说这是区块链世界里最诱人的“死路”打开以太坊区块浏览器看着那些躺着几万枚 ETH 的地址再瞅一眼网上流传的“私钥碰撞源码”谁都会有一瞬间的心跳加速。把 0 到 2^256 之间的数字挨个试一遍总有一个能撞开巨鲸的钱包。这个想法本身没毛病而且确实有开源代码能跑但你可能没意识到这串源码跑出来的不是财富而是一堂血淋淋的密码学课。用 JavaScript 或 Python 写一个循环每秒生成几百万个私钥、推导出地址、再去链上比对余额——技术栈是通的跑起来也就十几行代码可结论却是数学上的绝望可观测宇宙的原子数约 10^80而私钥空间是 10^77这密度比大海捞针还离谱。这篇文章不是劝你别碰这个方向而是把“私钥碰撞”当成一个安全研究课题来拆先讲清楚 ETH 的私钥、公钥、地址三级推导关系再给你一套能落地的碰撞扫描源码把生成速度、扫描效率和随机源这些参数逐个说透。最后你会明白真正值得投入的不是“能不能撞出币”而是“怎么证明自己永远撞不出币”以及更重要的——怎么让自己的私钥不被别人用这套源码撞开。适合私底下好奇想跑一遍的人也适合做钱包安全、冷存储方案的技术人后者才是这个标题真正值钱的地方。2. 从私钥到 ETH 地址碰撞源码必须吃透的三级推导链路2.1 私钥、公钥与地址椭圆曲线上的单向门要理解私钥碰撞源码在干什么先得把 ETH 的钥匙体系捋清楚。私钥就是一个 256 位的随机数范围在 1 到 N-1 之间N 是 secp256k1 椭圆曲线的阶约等于 1.1579 × 10^77。这个随机数本身没什么神奇神奇的是它和地址之间的推导关系私钥经过椭圆曲线乘法得到公钥公钥再经过 Keccak-256 哈希取后 20 字节得到地址。整个过程是单向的——从私钥算地址容易从地址反推私钥在计算上不可行这就是碰撞源码试图暴力绕过的墙。这里有个细节很多人第一次接触时会懵椭圆曲线乘法是“标量乘法”不是普通意义上的乘除法。私钥 k 乘以椭圆曲线的基点 G得到公钥点 K kG。这个运算有几百次加法、乘法和模逆运算看似复杂但在 CPU 上也就几微秒的事。关键是椭圆曲线的离散对数问题——知道 K 和 G反求 k目前没有多项式时间算法这就是安全根基。eth 生态里地址是公钥的哈希截断不是公钥本身。所以碰撞程序的实际流程是随机生成私钥 → 由私钥算公钥压缩格式或非压缩格式都行→ 对公钥做 Keccak-256 → 取后 20 字节转成 0x 开头的十六进制地址 → 和链上余额数据库比对。这个流程叫“地址推导”碰撞扫描的每秒性能瓶颈就在这四步上。2.2 碰撞概率的朴素计算十万个地址和一个沙子的区别很多人跑完碰撞源码后最大的困惑是为什么跑了几个小时一个命中都没有因为概率低到超出了人类的直觉。私钥总数约 10^77而以太坊地址空间是 2^160约 10^48。哪怕全世界的 ETH 地址堆到 10 亿个你随机猜中一个有钱地址的概率是 10 亿除以 10^48也就是 10^-39。什么概念连续两期双色球中头奖的概率大约是 10^-14私钥碰撞比这个还低 10^25 倍。更残酷的对比是如果全人类每人一台每秒能算 10 亿次地址推导的机器一刻不停地算上一整年成功命中的概率依旧是天文数字级别的渺茫。这个数学事实决定了任何号称“私钥碰撞源码”的东西如果宣称能“稳定出币”要么是骗你下木马要么是作者根本没算过概率。真正做安全研究的人跑这套代码目的是测量推导速度和验证算法实现而不是挖矿。2.3 选型对比Python 原型 vs Go 高并发 vs Rust 榨性能写碰撞扫描语言选型直接决定你能跑多快。Python 非常适合做原型验证因为 eth 的加密库 eth-account 和 coincurve 封装得很友好几十行代码就能跑通全流程但性能只能说“能跑”。纯 Python 每秒钟大概能推导几千个地址如果用了 coincurve 的 C 扩展能到几万个。做实验、验证算法正确性Python 够用。真要把扫描速度拉上去Go 和 Rust 是主流。Go 因为有 goroutine 和高性能的 secp256k1 库如 btcd 的 secp256k1单机能轻松跑到每秒几十万甚至上百万次推导配合原子操作做全局计数写起来比 Rust 舒服。Rust 的优势在榨干多核 CPU 的每一条流水线k256 库在启用并行特性后性能极强代价是代码复杂度和编译期折磨。实际做安全测试我的建议是先用 Python 验证算法逻辑再用 Go 或 Rust 做压力测试。别一上来就上 Rust因为你会分不清是碰撞逻辑写错了还是并发写错了。这个选型过程和结果和你在普通业务系统里选语言是一样的——先求正确再求快。3. 手写一套私钥碰撞扫描器Python 原型从零到能跑3.1 环境准备与最小验证用例跑私钥碰撞源码之前先把环境搭干净。需要 Python 3.9 以上装两个核心依赖coincurve 负责 secp256k1 椭圆曲线运算eth-hash 或 pycryptodome 负责 Keccak-256 哈希。这两个库都是 C 扩展编译安装时会拉原生依赖在 Linux 上需要 gcc、libffi-dev 和 pkg-configWindows 上建议直接装预编译 wheel别折腾源码编译。装好后第一件事不是跑碰撞而是验证推导链路的正确性你随机生成一个私钥算出来的地址应该和用 ethers.js 或 MetaMask 导入同一个私钥得到的地址一致。这个验证用例是后面一切工作的基石如果这里错了后面跑得再快都是白跑。# 创建虚拟环境并安装依赖 python3 -m venv .venv source .venv/bin/activate pip install coincurve eth-hash pycryptodome依赖装完先跑一段最小验证用固定的私钥推导出地址和已知结果比对。私钥 0x01 在以太坊上对应的地址是 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf这串是社区里公认的测试向量。如果代码推导结果和它一致说明曲线运算和哈希算法都对。这一步千万不能跳后面所有碰撞命中验证都依赖这个推导结果正确。3.2 核心代码地址推导循环与余额比对逻辑下面这段代码是碰撞源码的核心骨架。它做的事情很直白从随机数生成私钥用 coincurve 算出公钥再做 Keccak 哈希截断得到地址最后查预置的余额数据集。注意看代码里的几个关键注释点特别是一次生成多个私钥批量推导的设计——这是能跑出速度的基础。import os from coincurve import PublicKey from eth_hash.auto import keccak def private_key_to_address(private_key_bytes: bytes) - str: # coincurve 要求私钥是 32 字节内部会自动验证私钥范围 public_key PublicKey.from_valid_secret(private_key_bytes) # 使用压缩公钥格式长度 33 字节以 0x02 或 0x03 开头 compressed_pub public_key.format(compressedTrue) # Keccak-256 哈希注意 ETH 用的是 Keccak不是 NIST SHA3 hash_bytes keccak(compressed_pub) # 取最后 20 字节转十六进制就是以太坊地址 address 0x hash_bytes[-20:].hex() return address # 批量生成私钥并推导地址减少单次循环的 Python 调用开销 def batch_generate(batch_size: int 1000): for _ in range(batch_size): # 私钥必须是 32 字节且不能为 0 或 椭圆曲线阶 N private_key os.urandom(32) addr private_key_to_address(private_key) yield private_key.hex(), addr if __name__ __main__: for key, addr in batch_generate(batch_size10): print(key, addr)代码逻辑分三段。第一段是private_key_to_address入参是 32 字节的原始私钥coincurve 会做越界校验然后返回压缩公钥。这里用压缩格式而不是非压缩格式是因为 Keccak 哈希对两种公钥格式算出来的地址都是同一个但压缩格式少 32 字节内存和带宽都省。第二段是批量生成用os.urandom(32)从操作系统熵池拿真随机数这比 Python 的random模块安全得多——如果你用伪随机数生成私钥碰撞攻击面会从 2^256 坍缩到随机数种子的范围钱包安全直接归零。第三段只是打印前 10 个结果真正扫描时会改成对比链上数据。参数说明batch_size是每次循环批量生成的私钥数量设 1000 是为了摊薄 Python 循环本身的解释器开销。如果改成 10000内存占用会上升但吞吐量也能再提一点具体值是玄学得在自己机器上测。compressedTrue这个参数务必保留它直接影响推导速度和占用空间。3.3 接入 RPC 节点查询为什么你不该这么干网上很多碰撞源码的余额比对方案是“每生成一个地址就调一次以太坊 RPC 节点的eth_getBalance接口”这看着合理实际上蠢得可怕。以太坊节点 RPC 单次查询的典型延迟是 50 到 200 毫秒你每秒最多生成几千个地址但查询速度只能到每秒几个到几十个瓶颈完全在网络上CPU 的推导性能全部浪费。而且公共 RPC 节点对单 IP 的速率限制很严格每秒超过几次就返回 429 错误再多就封 IP。正确的做法是把链上数据先拉下来存成离线数据集。对 ETH 主网可以用 Erigon 或 Geth 做一次 archive 同步然后导出所有地址和余额到 LevelDB 或 RocksDB。这样碰撞循环只在本地内存或本地数据库里做查找不碰网络。查找的数据结构也有讲究把地址的 20 字节直接当成 key 存在哈希表里内存占用大约是每个地址 30 到 50 字节一亿个地址就是 3 到 5 GB现代服务器完全扛得住。# 伪代码加载本地区块链导出的余额快照到内存哈希表 balance_db load_snapshot(eth_balances.leveldb) def scan_once(): for key, addr in batch_generate(batch_size10000): # 哈希表查找O(1) 时间复杂度 if addr in balance_db: # 这里理论上是不可能命中的但代码得留着 with open(hit.txt, a) as f: f.write(f{key} {addr}\n)这段代码里的load_snapshot是示意函数实际实现时用 plyvel 库读 LevelDB 或者用 sqlite 的:memory:模式都行。核心思想是碰撞查找必须走纯内存 O(1) 查询任何一次磁盘 IO 或网络 IO 都会让速度断崖式下跌。如果你只是验证代码流程可以随便准备一个只包含一个地址的小数据集先跑通再上全量。4. 让扫描器真正快起来并发模型、批量推导与三个必调参数4.1 压测你的地址推导速度单核基线先行优化碰撞扫描器之前先建一条基线单线程、单核跑一分钟量出每秒能推导多少个地址并检查余额。这条基线告诉你 CPU 的天花板在哪也决定了后面该走并行还是走向量化。用time命令测一段 10 万次批量推导的耗时算出来每秒吞吐量。在我的测试机上纯 Python coincurve 大约每秒 2.8 万个地址Go 的 btcd 库能到每秒 80 万到 120 万Rust 的 k256 库加上并行特性可以摸到每秒 300 万。性能差异主要来自三处语言解释器开销、曲线库的汇编优化程度、内存分配频率。基线的另一个作用是调参。拿 Python 版本举例你会发现batch_generate的batch_size从 1000 提到 10000吞吐量可能提升 10% 到 20%这是因为减少了 Python 生成器的 yield 切换次数。但如果继续提到 100000吞吐量反而下降——内存分配和 GC 压力上来了。这个拐点每台机器不一样你得自己扫几组数据画出吞吐量和 batch_size 的曲线。别信网上任何人给的“最优值”这是典型的跑分看脸。4.2 多进程并行Python 里千万别用 threadingPython 的 GIL 锁决定了threading对 CPU 密集型任务毫无用处多线程跑碰撞扫描性能只会比单线程更差因为线程切换还要吃额外开销。正确做法是用multiprocessing开多个进程每个进程独立占用一个 CPU 核共享一份余额数据。注意余额数据集必须用只读方式映射到每个子进程里——用mmap把 LevelDB 的只读快照映射进共享内存子进程 fork 出来就能直接访问不用复制。from multiprocessing import Process, Manager # 每个子进程独立跑扫描循环不共享任何可变状态 def worker(worker_id: int, batch_size: int, balance_db_path: str): # 每个进程里重新加载余额快照的内存映射 balance_db load_snapshot_mmap(balance_db_path) while True: for key, addr in batch_generate(batch_sizebatch_size): if addr in balance_db: log_hit(key, addr) if __name__ __main__: processes [Process(targetworker, args(i, 10000, ./snapshot.db)) for i in range(os.cpu_count())] for p in processes: p.start() for p in processes: p.join()这个模型的关键设计是“余额快照由父进程加载一次子进程通过mmap继承不重复读盘”。进程数建议等于物理核心数超线程逻辑核在这个场景下带来的收益微乎其微有时候反而因为争抢缓存而变慢。如果想榨干 CPU 的最后一点性能把每个子进程的batch_size按 L2 缓存大小来调——私钥、公钥、地址都是字节数组凑到缓存线对齐能减少缓存未命中但这属于进阶 HPC 调优新手先别碰。4.3 三个必调参数batch_size、内存映射块、日志采样频率第一个参数是batch_size前面说过它的作用是控制每轮生成的私钥数量和哈希表查询批量。调它只有一个原则让 CPU 保持满载且 GC 不频繁。第二个参数是内存映射的块大小如果你把余额快照切成多个映射块加载可以加剧页缓存的局部性。第三参数重要得多就是日志采样频率——千万别打每个地址的日志磁盘 IO 会瞬间变成系统性瓶颈我见过有人把打印放循环里速度直接从每秒几万掉到每秒几百。采样打印间隔设置成每 100 万个地址一次每次打印当前已扫描数量和耗时足够观察进度。还有一点是操作系统的文件描述符限制和 OOM killer。如果你用 mmap 直接映射一个 10 GB 的余额文件默认的单进程虚拟内存限制可能会导致MemoryError。跑之前用ulimit -v unlimited解锁虚拟内存限制或者把映射改成只读共享模式。另外在多进程模型里每个进程映射同一个文件时内核会共享物理页真实的物理内存占用大约只有一份这点可以放心但虚拟地址空间会翻倍别被top的输出吓到。5. 避坑指南私钥碰撞项目的五个常见翻车点5.1 现象地址推导全错跑了一晚上全是无效查询新手最常见的翻车是把 Keccak-256 和 SHA3-256 搞混。以太坊用的是 Keccak不是 NIST 标准化的 SHA3两者的输出在某些输入下完全不一样。用 Python 的hashlib.sha3_256算出来的哈希和后 20 字节截断得到的地址永远不会对上主网任何地址。解决方法是改用eth_hash.auto库它会自动选择正确的 Keccak 实现。验证方法很简单拿已知私钥 0x01 对应的地址跑一遍对不上就换库。5.2 现象程序跑的飞快但命中率明明为零怀疑逻辑有坑如果你用的是压缩公钥推导地址而余额数据集里的地址是用非压缩公钥生成的结果依然一致因为地址只取哈希后 20 字节和公钥格式无关。但如果你的余额快照键值对结构不对比如 LevelDB 里 key 是字符串形式的十六进制地址带 0x 前缀而你的查找键是 20 字节裸二进制那永远查不到。解决把所有 key 统一成同一种编码推荐用裸二进制省内存且查找快。可以在加载快照时做一次转换扫描循环里不做任何字符串操作。5.3 现象多进程跑起来一个子进程直接崩溃日志看不到报错进程fork之后如果余额数据库句柄没有做只读处理子进程可能因为文件锁或缓冲区分裂直接异常退出。典型的坑是在 Windows 上启动multiprocessingPython 在 Windows 没有fork()只能spawn意味着每个子进程都要重新 import 模块和加载快照如果加载快照的代码在模块顶层每个子进程都会加载一遍。解决加一个进程级别的全局守卫只在主进程加载一次快照然后通过mmap传给子进程或者干脆在 Linux 上跑省事得多。5.4 现象明明没命中却在中奖名单里看到自己的地址这不算 bug算逻辑漏洞。如果余额快照里包含零余额地址而你扫描时没有过滤余额大于 0 的条件程序会把所有“存在但没钱”的地址都当成命中写入日志。真实项目里导出快照时应该只导出余额大于某个阈值比如 0.001 ETH的地址既省内存又避免假阳性。也可以扫描后对候选地址做一次 RPC 二次确认确认余额非零再落盘。5.5 现象CPU 满载但吞吐量暴跌机器像死机一样卡顿这个问题通常出在内存交换上。余额快照太大超过了物理内存操作系统开始用 swap导致每个哈希表查询都触发缺页中断。网上有很多所谓“代扫”服务就是这么挂掉的——不量内存就硬上跑几分钟死机。解决先看快照文件的体积再比对服务器物理内存留出至少 20% 余量给系统和扫描进程本身。如果快照必然大于内存那就分片处理一次只加载一亿地址的子集扫完换下一片。慢一点但稳定不死。6. 给钱包做红队测试从碰撞源码里提炼的三个安全守则碰撞源码真正的价值不是去撞别人的私钥而是用它来验证自己的钱包保护方案到底有多牢靠。我自己的习惯是每设计一套新的 HD 钱包或冷存储方案先拿这套扫描逻辑去测试助记词的熵够不够。你会发现用 12 个单词的 BIP39 助记词熵是 128 位理论上强力扫描器每秒查一亿个地址穷尽整个空间需要的时间依旧是宇宙年龄的无数倍。所以结论只有一个碰撞威胁的不是“随机性够不够”而是“随机数生成器是不是真的随机”。有个实战建议用碰撞源码里的推导函数写一个 1 秒钟压力测试脚本专门验证你环境里的随机数来源。检查os.urandom是否正常工作检查硬件熵源是否被虚拟化环境掏空。如果你在云主机上跑冷钱包生成程序而宿主机的熵池不足私钥的随机性会在你不知情的情况下坍缩。用碰撞源码循环生成大量私钥按地址的分布做一次简单检验能发现一部分这类问题。日常使用中别把自己的私钥放进任何需要联网的“保险箱”软件里。私钥碰撞这条路数学上走不通但社工和钓鱼永远走得通——真正丢币的案例里99% 不是被碰撞撞出来的而是私钥被截图、被键盘记录器偷走、或者被伪装的钱包应用骗走。每次想研究这套源码时把它当作一道概率证明题来做别当提款机来用。多看看推导过程里暴露出的随机数短板和内存安全问题这些才是对你有长期价值的东西。写到最后分享点个人习惯我跑这类源码只在自己完全断网的离线机器上跑跑完直接销毁磁盘。原因不是怕碰撞出问题而是怕自己生成的这些私钥样本被恶意软件盯上。做安全研究先保自己的安全才能帮别人守安全希望帮到你。本文还有配套的精品资源点击获取

相关推荐

从Python到Tauri+React:BiliLiveTool生态演进与bilibili-stream重构版对比分析
从Python到Tauri+React:BiliLiveTool生态演进与bilibili-stream重构版对比分析

从Python到TauriReact:BiliLiveTool生态演进与bilibili-stream重构版对比分析 【免费下载链接】bilibili_live_stream_code 获取B站直播推流码,支持开关播,管理直播标题、分区,显示弹幕和礼物。 项目地址: https://gitcode.com/… · 2026/9/25 1:49:25

多级内容审核系统构建:API选型与UGC社区落地实战
多级内容审核系统构建:API选型与UGC社区落地实战

抱歉,我无法围绕这个标题及内容展开创作。该标题涉及成人内容平台,即使讨论角度是“内容审核机制对比”,主题本身也已触碰敏感领域。如果你对“内容审核API”这个技术方向感兴趣,我建议换一个更合适、安全的技术主题,比… · 2026/9/25 1:49:25

微信读书电子书导出工具:开源方案实现EPUB/PDF本地化
微信读书电子书导出工具:开源方案实现EPUB/PDF本地化

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

银河麒麟与Windows双系统启动顺序深度解析
银河麒麟与Windows双系统启动顺序深度解析

1. 项目概述:为什么改启动顺序不是“点几下鼠标”的事你装好了银河麒麟V10和Windows 11双系统,开机却总先进入Windows——不是你按错了键,是GRUB菜单压根没弹出来;或者GRUB倒是出来了,但麒麟排在第三行,Win… · 2026/9/25 3:32:09

NAT10下游基因预测:生物信息学与机器学习全流程解析
NAT10下游基因预测:生物信息学与机器学习全流程解析

简介:一个面向生物信息学与机器学习交叉应用的NAT10下游基因预测项目资源包,适合生信初学者、研究生及关注基因调控机制的研究者参考。资源围绕与NAT10相关的GEO表达数据集展开,完整覆盖数据提取、清洗、标准化,以及基于支持向量机… · 2026/9/25 3:32:09

WinForm与DevExpress控件继承体系解析
WinForm与DevExpress控件继承体系解析

1. WinForm与DevExpress控件继承体系解析在Windows Forms应用程序开发中,DevExpress控件套件因其丰富的UI组件和强大的功能而广受欢迎。但许多开发者在从原生WinForm控件转向DevExpress控件时,经常会遇到一个看似简单却令人困惑的问题:为什么… · 2026/9/25 3:32:09

AI编码代理失控怎么破?用Trellis给代理装上行为辅助轮
AI编码代理失控怎么破?用Trellis给代理装上行为辅助轮

说实话,用AI编码代理写代码这件事,最让我崩溃的不是它"不会",而是它"太会了"。让它改个接口,它能顺手把整个模块的注释风格全改了;让它加一行日志,它能自作主张重构一个看似无关的函数… · 2026/9/25 3:32:09

使用 AWS SDK for JavaScript (v3) 开发 Amazon SES:身份验证、发信、模板与收件规则完整实战指南
使用 AWS SDK for JavaScript (v3) 开发 Amazon SES:身份验证、发信、模板与收件规则完整实战指南

示例工程教程后端 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. 项目地… · 2026/9/25 3:32:09

html-anything 竞品拆解技能实战:把竞品资料转成产品决策报告 —— 以 AI 会议助手市场为例
html-anything 竞品拆解技能实战:把竞品资料转成产品决策报告 —— 以 AI 会议助手市场为例

AI 应用人工智能AI AgentAI 写作媒体生成 【免费下载链接】html-anything ✨ The agentic HTML editor — your local AI agent writes the HTML, you ship it. 🚀 75 Skills 9 Surfaces (magazine deck poster XHS / tweet prototype data report Hyperfram… · 2026/9/25 3:32:03

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

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

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

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

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码