Java验证码实现:BufferedImage、Redis与AES加密的点击滑动验证码方案
简介针对网站登录、注册等场景的Java验证码实现方案覆盖点击文字验证码与拖动/滑动图片验证码两类交互形式面向需要快速集成或自研行为验证码的后端/全栈开发人员。源码基于JDK1.8、Spring Boot 2.1.17与Redis构建同时提供demo启动工程、单元测试与完整实现思路可直接参考改造投入生产。压缩包共178个文件约8.92MB包含68个Java核心源码、18个XML配置、15个CSS与13个JS前端交互文件以及PNG、JPG、GIF等图片素材和字体资源整体按点击、拖拽两个demo子项目组织目录清晰便于定位和学习。资源已有3078人学习浏览。内容上不仅给出前后端坐标加密AES/DES、随机中文文字生成、随机抠图与拼图等关键实现还梳理了点击坐标换算、拖拽轨迹校验和浏览器坐标偏移等设计要点配套demo与单元测试让读者能快速跑通流程并针对自身业务二次开发。1. Java验证码实现五个模块串起一套可上线的点击与滑动验证码做Web登录和活动页面的朋友应该都有体会图形验证码看着简单真正要接进生产环境的时候细节比想象中多得多。文字要随机、位置要随机、前端点击坐标和后端图片坐标要对齐、验证码还要有过期时间任何一个环节脱节用户就会卡在“请获取验证码”这一步。这套Java源码解决的问题正是这些用纯JDK的BufferedImage和Graphics2D生成点击中文文字验证码和拖动/滑动图片验证码Redis存校验缓存AES/DES加密坐标回传附带两个可直接启动的Spring Boot demo和单元测试。适合正在做用户行为验证、想省掉对接第三方验证码服务成本的Java工程师也适合把验证码实现当作Java面试题来研究的同学。2. 图片生成的核心BufferedImage、Graphics2D与随机文字/抠图2.1 点击文字验证码的生成思路点击文字验证码的交互逻辑是服务端生成一张背景图图上随机摆放若干个中文字再给用户一句提示“请点击其中的某个字”用户点击后前端把坐标传回后端判断这个坐标是否落在目标文字所在的矩形区域内。这个流程里最关键的其实是“文字区域”的算法而不是画图本身。在实现里生成背景图是先用BufferedImage创建一个画布BufferedImage bg new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d bg.createGraphics(); // 设置抗锯齿文字边缘更平滑避免用户看不清 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 用随机颜色填充背景干扰色与文字颜色错开 g2d.setColor(new Color(240, 240, 240)); g2d.fillRect(0, 0, width, height);这段代码做了三件事固定画布尺寸、打开抗锯齿、铺底色。width和height建议在配置里写成常量或者放到application.yml里我一般习惯设成300x150文字数量5个太小不好点太大会让页面显得突兀。接着生成随机坐标并画字ListWordInfo wordList new ArrayList(); String[] words {春, 夏, 秋, 冬, 月, 日, 山, 水}; for (int i 0; i 5; i) { // 随机选汉字、随机直径、随机坐标 String word words[new Random().nextInt(words.length)]; int fontPx 28 random.nextInt(16); int x random.nextInt(width - 60); int y random.nextInt(height - 40); g2d.setFont(new Font(宋体, Font.BOLD, fontPx)); g2d.setColor(new Color(random.nextInt(120) 60, random.nextInt(120) 60, random.nextInt(120) 60)); g2d.drawString(word, x, y); // 这一步很关键把字体的矩形区域记录下来用于点击命中判断 FontMetrics fm g2d.getFontMetrics(); Rectangle2D bounds fm.getStringBounds(word, g2d); wordList.add(new WordInfo(word, x, y, (int) bounds.getWidth(), (int) bounds.getHeight())); }这里的参数值得单独说明fontPx用28到44之间的随机值既保证可读性又避免每次都一样x取随机数时留出60像素的边距防止文字画出画布y在drawString里是文字的基线不是文字顶部所以用fm.getStringBounds取实际边界再判断命中。WordInfo就是存文字内容、坐标和宽高的DTO后端校验时直接遍历它。后端校验的逻辑就一句话boolean hit false; for (WordInfo w : wordList) { if (clickX w.getX() clickX w.getX() w.getWidth() clickY w.getY() clickY w.getY() w.getHeight()) { hit true; break; } }这段代码不复杂但有一个容易被忽略的细节getStringBounds返回的矩形是相对基线坐标的x和y的偏移和drawString传入的坐标并不是简单相等的。实战里我见过不止一次因为这里没换算导致永远校验不通过的情况。2.2 滑动图片验证码的抠图与拼图滑动验证码的图生成思路不太一样它需要一张背景大图、一张抠出来的滑块小图、以及记录滑块原始位置和拼图目标位置的两组坐标。生成过程中最有趣的部分是“随机抠图”完全可以用Graphics2D的setClip配合Path2D实现不需要引入任何第三方图像处理库。抠图的典型实现BufferedImage bgImage ImageIO.read(new File(bg.jpg)); BufferedImage slider new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB); Graphics2D sg slider.createGraphics(); // 生成一个不规则圆形路径模拟手指按压的缺口效果 Path2D path new Path2D.Float(); int centerX 25, centerY 25; for (int i 0; i 360; i 15) { double radius 20 random.nextInt(5); double angle Math.toRadians(i); if (i 0) { path.moveTo(centerX radius * Math.cos(angle), centerY radius * Math.sin(angle)); } else { path.lineTo(centerX radius * Math.cos(angle), centerY radius * Math.sin(angle)); } } path.closePath(); // 先按路径抠出原图上的缺口部分再画到滑块透明图上 sg.setClip(path); sg.drawImage(bgImage, 0, 0, null);这段代码里Path2D生成的是一个多边形近似的圆半径在20到24像素之间抖动视觉上接近真实的“缺口”感。抠图的做法是先创建透明底的滑块画布设置clip路径后把背景图直接画进去因为裁剪作用只有路径范围内的像素会落到滑块图上。拼图目标位置就是背景图上缺口应该补齐的位置这个坐标通过随机生成一个x值然后去原图对应区域截图备用。我这里要提醒一个选型点滑块大小50x50是常用配置但如果你要在手机上用建议做成等比缩放。移动端手指触摸范围比鼠标大滑块太小容易拖不准常见的做法是把背景图宽度拉到600像素以上滑块对应放大到60像素。2.3 Redis在验证码流程里的职责Redis在整个流程里承担的事情是“短期缓存校验数据”。点击验证码或滑动验证码生成后服务端要把目标文字或目标位置的坐标、验证码ID、过期时间存进Redis用户提交校验时再去取。这个设计方便验证码一次性使用校验成功立即删除也方便控制过期时间。存取的典型代码// 生成验证码后把答案和过期时间写入Redis String codeId UUID.randomUUID().toString().replaceAll(-, ); redisTemplate.opsForValue().set(captcha: codeId, JSON.toJSONString(answer), 5, TimeUnit.MINUTES);// 用户点击提交后从Redis读答案并比对 String answerJson redisTemplate.opsForValue().get(captcha: codeId); if (answerJson null) { throw new RuntimeException(验证码已过期); } CaptchaAnswer answer JSON.parseObject(answerJson, CaptchaAnswer.class);这里的key前缀建议统一用captcha:方便管理过期时间我习惯设成5分钟太短用户填表单容易中途失效太长又有被撞库的风险。另外要留意生产环境Redis必须开密码访问至少在application.yml里配上spring.redis.password别把6379端口裸奔到公网。3. 前端坐标计算与后端校验逻辑3.1 点击事件坐标怎么算才不出偏差后端生成的图片最终会通过接口返回给前端渲染在页面上。用户点击的坐标是浏览器事件里的clientX和clientY但这两个值是相对浏览器窗口的如果要映射到图片本身上必须减去图片在页面中的偏移量。这是一个很典型的坑代码并不复杂但少了任何一步都会产生系统性偏移。前端计算点击相对坐标的写法function handleClick(e) { const img document.getElementById(captchaImg); const rect img.getBoundingClientRect(); // 关键减去图片左上角相对viewport的位置再加上滚动偏移 const x e.clientX - rect.left; const y e.clientY - rect.top; // 如果页面产生了滚动还要把scrollTop和scrollLeft加回来 const scrollX window.pageXOffset || document.documentElement.scrollLeft; const scrollY window.pageYOffset || document.documentElement.scrollTop; const relativeX x scrollX; const relativeY y scrollY; sendClick(relativeX, relativeY); }这段代码里有两点值得细说。第一getBoundingClientRect返回的是相对视口的坐标如果页面本身没滚动rect.left和rect.top就等于图片在文档流中的偏移第二如果验证码弹窗在页面中间且页面可以滚动用户滚动后再弹窗坐标会整体偏移所以相对坐标要加回scroll值。我在实际项目里会让前端同时回传图片的实际渲染尺寸后端按比例换算避免图片被CSS压缩导致坐标失真。3.2 滑动拖拽的距离校验与容错区间滑动验证码的校验逻辑比点击验证码多一层不仅要判断最终落点是否匹配还要判断拖拽轨迹是否像真人。后端的滑动校验通常拆成两步第一步校验滑动距离是否在误差范围内第二步校验轨迹数据里的行为特征。一个最基本的校验代码int targetX answer.getTargetX(); int leftX userReport.getLeftX(); int distance Math.abs(targetX - leftX); // 滑块的宽度是50所以误差允许50像素内的偏差 if (distance 50) { return Result.fail(拖到正确位置后再松手); }误差区间设多少取决于滑块宽度。滑块宽50像素误差上限通常取滑块宽度的一半到等宽之间也就是25到50像素。设得过小会误伤用户设得过大就失去了验证意义。至于轨迹校验常见的做法是记录鼠标拖动过程中的每一组坐标和时间戳分析是否有突然的跳变或者拖动总时长是否小于300毫秒——如果是大概率是机器操作直接拒绝。3.3 坐标回传为什么要用AES/DES加密如果前端坐标直接明文传给后端攻击者只需要用浏览器开发者工具看接口返回和提交参数就能拿到目标坐标直接构造请求绕过验证。这个源码里用AES对坐标信息做加密目的就是提高抓包改包的成本。加密用的密钥可以由服务端在生成验证码时下发也可以前后端约定固定密钥。AES加密坐标的示意代码public static String encrypt(String content, String aesKey) throws Exception { SecretKeySpec keySpec new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), AES); Cipher cipher Cipher.getInstance(AES/ECB/PKCS5Padding); cipher.init(Cipher.ENCRYPT_MODE, keySpec); byte[] encrypted cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)); return Base64.getUrlEncoder().encodeToString(encrypted); }3.2 看不懂也先别改三个最容易改坏的参数滚动验证码里有一个参数组合我几乎每次接手项目都要提醒身边的人别乱改允许误差、轨迹采样频率和最小拖动时长。允许误差是像素级的和滑块大小直接相关如果你把滑块从50px放大到60px误差上限不跟着调翻新过的项目就会出现“明明滑块对准了却提示失败”的奇怪现象。采样频率决定了前端以多长间隔上报坐标常见的是每30毫秒到50毫秒记录一次。太密数据量大太疏轨迹特征不明显服务端很难区分人和机器。最小拖动时长一般是300毫秒到500毫秒小于这个时间直接判定为程序模拟因为真实人类不可能瞬间启动又瞬间停止。我在做这类项目的时候会把这三个参数集中放在一个常量类里让前端同学和后端同学共用一个文档避免前端写死了500毫秒、后端校验的是800毫秒两边对不上。这种看似小细节的问题在联调阶段是最消耗时间的。4. 部署AdemoIdea导入与Redis配置Maven打包与验证码模块的单元测试4.1 从Maven工程到Spring Boot应用source包里是两个独立的Spring Boot子项目一个负责点击文字验证码一个负责滑动图片验证码直接以Maven工程导入Idea就能看到结构。导入的时候选择Maven项目类型等依赖下载完再动手改代码Spring Boot 2.1.17.RELEASE的依赖树比较长第一次加载可能耗时几分钟。两个子项目共用一个父POM主要做的配置是锁定Spring Boot版本和统一依赖版本。4.2 Redis配置与打包启动在IDE里运行demo前必须先改application.yml里Redis的连接地址否则启动不报错但所有验证码接口都会返回“生成失败”。在线体验过程中最常翻车的不是Java代码而是Redis本身。我一般建议本地直接跑Docker Redis命令很简单docker pull redis:5.0 docker run --name captcha-redis -p 6379:6379 -d redis:5.0然后修改resources/application.yml里的spring.redis配置spring: redis: host: 127.0.0.1 port: 6379 timeout: 3000ms server: port: 80814.3 打包命令与启动打包需要跳过去单元测试如果Redis没启动test下的Redis连接测试类会报错为了快速验证demo可以跳过测试mvn package -Dmaven.test.skiptrue打包完成后target目录下会生成可执行jar直接运行点击验证码demo是ClickCaptchaApplication滑动验证码demo是DraggedCaptchaApplicationjava -jar target/dragged-captcha-1.0.0.jar4.4 单元测试的用途别把它当摆设单元测试在这份资源里的作用不是用来凑执行率的而是给你一个可重复运行的“接口验收名单”。点击验证码的单元测试会直接调用生成接口的service层方法检查返回的codeId是否存在、Redis里是否写入了对应key、答案坐标是否在图片范围内。滑动验证码的单元测试则更关注抠图出来的滑块区域是不是透明底的以及拼图坐标是否落在合理区间。我接手类似项目会先跑一遍测试确认环境正常再去看业务代码。本地跑的时候如果测试报错大概率是字体缺失或者Redis版本兼容性问题业务代码反而是次要的。5. 避坑与排查从“验证码不显示”到“坐标老是差几像素”5.1 验证码图片拉取超时现象前端发起GET请求拿验证码图片页面一直转圈最后接口超时报500。 原因Redis连接失败或Redis没启动coreService里生成答案后写入缓存失败异常直接抛给了前端。 解决先看Redis是否存活执行redis-cli ping看是否返回PONG再看application.yml里的host是不是127.0.0.1还是服务器的内网IP。如果是云服务器部署还要检查安全组是否放行了6379端口。5.2 页面弹窗里点中文永远提示“点歪了”现象浏览器控制台打印出的坐标明明是整百的数字后端却返回“位置不准确”。 原因前端用了事件对象里的offsetX和offsetY而这个属性的参考对象是触发事件的目标元素。如果代码里把事件绑定在canvas或img的父容器上坐标参考系就变成了父容器位置自然偏移另一个常见的坑是图片渲染后被CSS拉伸坐标没有按比例换算回去。 解决统一用getBoundingClientRect方式计算相对坐标提交时带上图片的实际渲染宽度和原始宽度后端在做容错比较前先把坐标缩放回原始画布比例。5.3 中文字体在我的Linux服务器上变成了方框现象本地Windows开发一切正常部署到CentOS服务器后验证码图片上的中文全部显示成豆腐块。 原因服务器上没安装中文字体。JDK的Graphics2D找不到汉字字体时不会报异常而是用默认字体尽力渲染结果就是方框。 解决在服务器上执行yum install fontconfig并复制一套Windows字体到$JAVA_HOME/lib/fonts下或者更稳妥的方案是直接用项目资源目录下的ttf文件通过Font.createFont加载并注册到GraphicsEnvironment这样无需依赖服务器系统字体。5.4 验证码刷新太频繁Redis里堆积大量脏key现象用户每点一次刷新就生成一个新的codeId但旧的把关数据一直存在Redis里内存持续上涨。 原因过期时间虽然设了5分钟但极端情况下用户高频点击刷新同一会话可能在一分钟内生成几十个key全部留存到5分钟后才淘汰。 解决每次生成新验证码时把当前会话的旧codeId在Redis里做一次删除或者在缓存key中带上会话标识例如captcha:sessionId:uuid这样删除时可以直接模糊清理。我一般会在生成方法开头先清理该会话下的旧key。5.5 AES加密后的坐标串在GET请求里丢失现象点击后提交数据后端经常解密失败但自己的本地测试一切正常。 原因AES加密后生成的Base64字符串里可能包含、/、这些URL保留字符放到GET请求的queryString里会被自动转义或截断导致后端拿到的密文和加密时的字符串不一致。 解决URL编码一次再传输或者使用Base64.getUrlEncoder()生成URL安全的字符集把转成-、/转成_。后端解密前统一用URLDecoder.decode做好解码避免因框架本身解码一次后仍不干净。6. 进阶验证法从能用到敢上生产线的实操习惯验证码这类组件最怕的不是写不出来而是写完自己觉得没问题、一到线上就暴露问题。我后来给自己定了一条硬规矩任何验证码改动必须跑四类验证——功能测试、并发测试、跨天测试、坐标偏差统计测试。跑法其实不复杂功能测试就是对着demo点一遍确认正常路径能过、乱点能拦并发测试用两个浏览器同时刷新页面看看Redis里的key是不是互相覆盖跨天测试在前一天生成验证码、第二天再提交确认过期逻辑真正生效坐标偏差统计是拿着后端日志里所有成功校验的坐标差画一个表看看用户提交的成功坐标偏离目标点多少像素这能替你检验误差上限设置到底合不合理。我还习惯在在本地把demo里的单元测试跑起来把里面的断言当作一份活文档。比如点击验证码的测试会断言“错误坐标校验失败”“正确坐标校验成功”“重复校验第二次失败”这比任何注释都直观。核心提示别为了过测试而无条件放宽误差上限误差是对抗脚本的防线放宽到100像素以上这个验证码就形同虚设了。诚实地讲每次接这类项目我都是先从这套代码的单元测试看起再去看生成和校验逻辑最后一件事才是配Redis联调页面。不过这套逻辑并不只适用于这个仓库它是我一贯的做法——先让机器替你跑一遍再让用户替你点一遍。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

端侧AI部署底层逻辑:从张量布局到NPU性能瓶颈

端侧AI部署底层逻辑:从张量布局到NPU性能瓶颈

做了快十年的端侧 AI 部署工作,有个问题我几乎每隔几天就会遇到一次:同一个模型在 GPU 云主机上跑得飞快,一到手机、开发板、工业盒子上就卡得怀疑人生。问题很少出在模型本身,大概率是底层的执行链路没理顺——从张量&#xff08…

2026/10/7 5:31:09 阅读更多 →
嵌入式分享#63:RK3588 怎么选?全系列选型指南

嵌入式分享#63:RK3588 怎么选?全系列选型指南

嵌入式分享#63:RK3588 怎么选?全系列选型指南 最近几年,RK3588 在嵌入式圈子里热度确实很高。 不管是开发板、边缘计算盒子、NVR、工控机、AI 视觉,还是多屏显示项目,经常都能看到它的身影。 原因也不复杂:…

2026/10/7 5:31:09 阅读更多 →
GitHub日榜怎么看?从热榜项目评估到开源代码复现实战

GitHub日榜怎么看?从热榜项目评估到开源代码复现实战

GitHub 热榜项目是个很有意思的东西,它不像新闻那样只有信息,更像是一张每天都在更新的“行业活地图”。不管是做开发的、搞研究的,还是单纯想找点效率工具的人,几乎都能在日榜里翻到和自己相关的东西。我习惯每天早上打开 GitHub…

2026/10/7 5:30:09 阅读更多 →

最新新闻

XPay原理与部署:Java个人收款到账监听与回调实现

XPay原理与部署:Java个人收款到账监听与回调实现

简介:XPay V3.1是一套基于Java开发的个人收款支付系统,专为个人站长、独立开发者及小微企业设计,完全免费且无需签约,生成个人收款码后即可收款,交易资金直接进入本人账户,有效破解传统支付接入门槛高、结算…

2026/10/7 5:54:25 阅读更多 →
SpringBoot财务管理系统毕业设计:从建表到凭证复式记账的完整实现

SpringBoot财务管理系统毕业设计:从建表到凭证复式记账的完整实现

简介:面向计算机相关专业毕业设计场景的Java财务管理系统完整项目,基于Spring Boot框架开发,包含前后端源码、毕业论文与答辩PPT,适合需要快速搭建财务系统课题或学习企业级分层开发的毕业生与开发者。资源包共452个文件&#xff…

2026/10/7 5:54:25 阅读更多 →
Minecraft模组加载器编年史:从Forge到Fabric,破解崩溃日志与版本选型

Minecraft模组加载器编年史:从Forge到Fabric,破解崩溃日志与版本选型

我第一次把Minecraft Java版玩到崩溃,是在2012年某个燥热的午后。我对着贴吧教程,把两个jar文件拖进了mods文件夹,然后点开启动器,看着进度条走到一半,屏幕一黑,弹出一片白底黑字的报错。我不认识任何一个英…

2026/10/7 5:54:25 阅读更多 →
无锁环形队列与自适应数据总线:游戏日志高性能设计解析

无锁环形队列与自适应数据总线:游戏日志高性能设计解析

先说个背景:这篇是BqLog系列的第二篇。上一篇我把BqLog的整体架构、线程模型和它为什么敢把日志写进游戏进程里聊了一遍,当时很多读者问“环形队列到底怎么做到无锁”“自适应数据总线到底是什么”,今天这篇就专门拆这两个点。王者荣耀的日志…

2026/10/7 5:54:25 阅读更多 →
Altium Designer差分对设计:等长等距与阻抗控制实操指南

Altium Designer差分对设计:等长等距与阻抗控制实操指南

做高速板子的朋友,十有八九都被差分对折磨过。眼图打不开、误码率高、认证过不了,查一圈图纸,最后往往发现在Altium Designer里差分对的等长和等距做得太随意。我先说个真实经历:去年调一版PCIe转接板,功能倒是正常&am…

2026/10/7 5:54:25 阅读更多 →
卡通风格工地临时工作区场景搭建:从关键词拆解到渲染的完整流程

卡通风格工地临时工作区场景搭建:从关键词拆解到渲染的完整流程

1. 从“外景 工地 卡通风格工地 临时工作区”这组词里,我读出了什么第一次看到“外景 工地 卡通风格工地 临时工作区”这组词的时候,我脑子里蹦出来的不是某个具体的软件,而是一整套视觉资产的搭建流程。这组词看起来像是素材库里的标签组合&…

2026/10/7 5:53:25 阅读更多 →

日新闻

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

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

2026/10/7 1:01:58 阅读更多 →
用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

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

2026/10/7 1:02:00 阅读更多 →
芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

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

2026/10/7 1:02:00 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/6 7:15:40 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/6 5:29:09 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/6 6:26:51 阅读更多 →

月新闻

我发现了一个新思路:用 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/6 8:21:32 阅读更多 →
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/6 4:21:51 阅读更多 →
黑夜航拍船只数据集训练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/6 1:18:13 阅读更多 →