单片机MD5校验原理与移植避坑:从资源适配到固件升级实践
简介面向瑞萨、ST及上海东软等常见MCU平台这套MD5加密源码为单片机开发者提供了可直接移植的哈希算法C实现适用于数据完整性校验、密码存储与防篡改等嵌入式安全场景。压缩包仅含1个C源文件和1个头文件整体约3KB结构极简C文件包含初始化、分组处理、填充及摘要生成等完整流程头文件则定义相关结构体与函数原型便于快速集成到现有工程。实现覆盖MD5核心四步寄存器初始化、64轮迭代运算、消息填充与长度附加、128位摘要输出并针对单片机内存与算力受限的特点做了精简处理可降低资源占用实际使用时还需根据具体芯片的编译器与指令集进行少量适配。已有805人学习、下载适合具备基础C语言和单片机开发经验的读者直接用于项目改造或参考学习。1. 单片机MD5加密名字叫加密实际做校验落地前先想清楚RAM和时序单片机MD5加密这个词在很多嵌入式需求文档里反复出现但它在算法分类上和AES、RSA完全不是一个阵营MD5是散列摘要不是可逆加密它的本职工作是给一段数据算一个固定长度的指纹用来确认数据有没有变化。做设备接入、固件升级、参数校验的人需要这个功能但同时也是最容易踩坑的因为MD5对单片机并不算一个调好库就能跑的黑匣子资源的分配、字节序、分片更新、中断重入都会影响最终结果。这篇文章会从原理、源码选型、工程接入到避坑排查走一遍让新手能照着把代码跑通让熟手也检查一下自己容易忽略的几个边界。2. MD5原理与单片机资源适配先想清楚算的是什么再评估跑不跑得动2.1 MD5算法结构填充、分块、四轮循环与状态变量MD5处理任意长度输入时先把数据分成512位的块。最后一个块需要填充先补一个二进制1再补一堆0直到剩下64位用来放原始消息总长度长度单位是位并且按小端存储。这个填充动作通常由MD5_Init、MD5_Update执行过程中自动完成到MD5_Final才会补齐最后一块。理解它有助于排查边界错误尤其是处理0字节、63字节、64字节、65字节这类临界长度时容易出现反常识的结果。每个512位块会被拆成16个32位小端字。算法维护四个32位状态变量A、B、C、D初始值固定为0x67452301、0xefcdab89、0x98badcfe、0x10325476。每个块要做四轮处理每轮16步总共64步。四轮对应的逻辑函数分别是F、G、H、I全部由位运算组成F (B C) | (~B D)G (B D) | (C ~D)H B ^ C ^ DI C ^ (B | ~D)每次循环还要加上输入字、常数T[i]和当前状态然后做一次循环左移。常数T[i]是一张64项的固定表由正弦函数生成在源码里基本以常量数组形式出现。这里需要把概念纠正过来MD5是消息摘要算法没有密钥正向计算很快反向基本不可行但它存在碰撞风险。所以需求文档里写MD5加密时实际要的是完整性校验确认数据没有被改而不是把数据内容藏起来。如果需求写的是加密通信保密应该去选AES如果需求是固件校验、下载包完整性MD5才上场。这个判断做错了后面整个设计都会跑偏。MD5对单片机友好的一点是它没有字符串、没有动态分配、也不依赖外部硬件。输入数据在缓冲区里凑满64字节就压缩一个块剩下不足64字节的留到下一次。因此算法天然适合分片处理这正好符合嵌入式系统数据一包一包来的常态。2.2 单片机资源盘点RAM、ROM和耗时怎么估算一个经典C实现的MD5上下文结构体包含四个状态变量16字节、64字节消息缓冲区、8字节长度计数再算上函数内部的临时变量整体占用约90到100字节RAM。如果使用全局上下文它固定在静态区不受栈深度影响如果定义在函数栈上则需要额外关注任务栈大小。ROM占用主要由代码段和常量表组成。代码段是算法核心和三个接口函数通常在2KB左右T常数表固定占用256字节。整体ROM增量在3KB到6KB之间。芯片Flash只有8KB的时候要仔细裁剪Flash在64KB以上基本不用纠结。耗时估算有两种办法。第一种按算法步数粗算每个64字节块要做64步每步一次加法、一次移位、一次逻辑运算在常见32位单片机上每步大约几十个周期每KB数据约等于16个数据块。第二种是实测量把需要计算的500字节数据放到一个函数里翻转一个GPIO用逻辑分析仪或示波器量耗时。我做项目时偏向后者因为编译器优化、总线等待、Flash读取速度都会带来偏差理论算出来的数字只够用来判断是不是该放到后台任务去跑。低功耗场景要考虑得更细。如果单片机长期跑在低频模式唤醒后连续计算大报文电流尖峰和总耗电都会变高。建议把MD5计算放在刚唤醒、准备进入睡眠前的时间段不要在中断里分多次执行。2.3 源码选型适合单片机的MD5实现应有这几个特征网上能找到的MD5源代码很多但不少是给PC环境写的直接搬进单片机工程会带出一堆问题。我选单片机MD5源码时先做四件事。第一查依赖。源码是不是只用标准C的整数类型和内存操作有没有用到文件读写、动态内存、printf。出现fopen、malloc、FILE这类符号说明源码和嵌入式环境不匹配。正确的做法是输入数据通过接口传入算法内部不碰文件系统。第二查上下文。所有中间状态包括state、count、buffer都应该封装在一个结构体里。这样一个计算流程只依赖一个上下文对象可以被复制、暂停、恢复。如果源码使用全局state两个独立的数据流同时计算就会互相覆盖这种源码在嵌入式项目里基本不可用。第三查接口。必须提供类似MD5_Update(ctx, data, len)的分片更新接口允许传一段数据算一部分再传下一段继续算。没有分片接口的源码要求调用方一次性把完整数据传进来这在单片机里往往不现实因为没有哪个设备会为了算校验把整个固件镜像搬进内存。第四查可配置性。源码是否能在-O2优化下编译常量表是否可以放到只读数据段是否用了变长数组或递归。变长数组和递归在小栈单片机上都有隐患。尽量选纯函数式、可重入的代码以后调试和移植都省事。如果找不到满意的源码自己按标准实现一个精简版也不难。后面一章会给一个最小接口和典型接入流程照着改通常比修一份陌生的PC源码快得多。2.4 先用固定测试向量自检再进业务代码不管从哪份源码开始移植第一步都不是接业务代码而是用标准测试向量验证算法本身。MD5最常用的测试向量是abc字符串标准摘要为900150983cd24fb0d6963f7d28e17f72。空字符串的摘要为d41d8cd98f00b204e9800998ecf8427e。这两个够用前者覆盖非空数据后者覆盖长度为0的边界。在单片机工程里写一个临时自检函数完整代码如下/* 自检函数计算abc的MD5与标准摘要比对 */ uint8_t test_input[] abc; uint8_t expect[16] { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 }; uint8_t digest[16]; MD5_CTX ctx; MD5_Init(ctx); MD5_Update(ctx, test_input, 3); MD5_Final(digest, ctx); if (memcmp(digest, expect, 16) 0) { /* 算法正确 */ } else { /* 移植有误立即排查 */ }这里最需要注意的是test_input数组用3而不是sizeof(test_input)因为sizeof会包含结尾的\0计算结果就会和标准摘要不一致。很多新手第一次自检就在这个细节上翻车。我还有个血泪经验第一次移植时在PC上调通了烧到板子上却发现只有abc对得上长一点的报文全错。原因不是算法本身而是输入缓冲区没有做内存对齐32位指针直接访问了未对齐地址在常见32位内核上触发硬件异常。后来我改成用memcpy把每4字节拷到一个临时uint32变量再参与运算问题消失。所以自检阶段不仅要看摘要对不对还要故意测几种长度0字节、1字节、63字节、64字节、65字节、512字节。这些边界值能一次性暴露填充、长度进位和缓冲区拼接的手是问题。3. 移植MD5源代码最小接口、分片调用和内存优化3.1 头文件与上下文结构体先建立一个不依赖平台的数据类型MD5不在标准库里所以头文件需要自己定义。下面是一个通用性很强的md5.h我习惯在写业务代码之前就把这个文件定好。// md5.h #ifndef MD5_H #define MD5_H #include stdint.h typedef struct { uint32_t state[4]; /* 当前摘要状态 A, B, C, D */ uint32_t count[2]; /* 已处理的字节数2个32位拼接成64位 */ uint8_t buffer[64]; /* 等待被压缩的输入块缓冲区 */ } MD5_CTX; /* 初始化上下文 */ void MD5_Init(MD5_CTX *ctx); /* 向正在计算的数据流中追加数据支持多次调用 */ void MD5_Update(MD5_CTX *ctx, const uint8_t *data, uint32_t len); /* 完成处理输出16字节完整摘要 */ void MD5_Final(uint8_t digest[16], MD5_CTX *ctx); #endif这里所有类型都用uint8_t、uint32_t保证在8位和32位单片机上宽度一致。count数组用两个32位是因为64位整数在8位机上处理很慢拆成两个32位后每次更新只需要处理低32位溢出时进位到高32位。buffer固定为64字节正好一个512位块。MD5_Update每次调用会先把数据拷贝进buffer凑满64字节就压缩一次剩下不足64字节的留在buffer里等MD5_Final再填充和压缩。3.2 一次性计算和分片计算两个调用模型对单片机开发者来说最常用的调用有两种。第一种是短数据一次性算完例如校验一条命令、一个结构体/* 计算一个短结构体的MD5摘要 */ uint8_t md5_result[16]; MD5_CTX ctx; uint8_t payload[] {o, p, e, n, 0x00, 0x01}; MD5_Init(ctx); MD5_Update(ctx, payload, sizeof(payload)); MD5_Final(md5_result, ctx);payload里含有一个0x00字节如果用strlen就会提前截断。这里必须用sizeof(payload)得到6字节。MD5_Final拿到的是16字节二进制摘要不是十六进制字符串需要打印时再自己做转换。这个逻辑是只要参与计算的字节序列和PC端完全一致摘要就一定一致。第二种是长报文分片计算。固件升级时整个镜像可能几兆字节不能一次性搬到内存而是一边从Flash或通信接口读数据一边算。示例MD5_CTX ctx; uint8_t digest[16]; uint8_t chunk[512]; uint32_t total_len; uint32_t offset 0; MD5_Init(ctx); while (offset total_len) { uint32_t read_len (total_len - offset sizeof(chunk)) ? sizeof(chunk) : (total_len - offset); read_data_from_flash(chunk, offset, read_len); /* 项目里的读取函数 */ MD5_Update(ctx, chunk, read_len); offset read_len; } MD5_Final(digest, ctx);每次分片长度可以从16字节到2KB不等MD5_Update内部会处理跨块边界。分片太小会导致函数调用过多分片太大则浪费调用方缓冲区。我一般选512字节刚好和常见Flash页大小或通信缓冲区对齐。这里注意read_data_from_flash只是一个示意实际工程里要替换成你项目里的读取函数并保证每次读取的地址和长度正确。3.3 核心实现里的三个关键参数初始值、移位位表、T常数如果你拿到的是一份标准C实现核心代码里会有四段对应四个逻辑函数。每段里都有三个关键参数移植时任何一个改错摘要都会错。第一是状态初始值。A0x67452301B0xefcdab89C0x98badcfeD0x10325476。它们写在MD5_Init里。注意这些32位常量在内存中的小端存储顺序用调试器看内存时字节顺序可能和书写相反这是正常的。第二是循环左移位数。标准实现里每一位的移位量来自一个固定序列例如第一轮用7、12、17、22循环第二轮用5、9、14、20循环。如果源码里的S数组或switch分支数字改错所有摘要都会错。第三是T常数表。标准T[i]等于4294967296乘以abs(sin(i))的整数部分i从1到64。源码里通常会直接给出64个uint32_t常量例如T[1]0xd76aa478T[17]0xf61e2562。对照标准表逐项核对是移植后自查最有效的手段。每步运算的核心是类似A B rotate_left(A F(B,C,D) X[k] T[i], s)的表达式。这里的A、B、C、D、X[k]都必须是uint32_t。如果在代码里为了省事用了unsigned int而编译器把unsigned int当16位处理结果就会出错。这种问题在8位单片机上尤其容易发生所以我在关键运算处显式使用uint32_t不用平台相关的默认类型。3.4 内存优化上下文放全局、临时缓冲去掉、常量放只读区小RAM单片机上主要有三个优化手法保证MD5跑得动。第一把MD5_CTX定义成全局变量而不是定义在函数栈上。全局变量占用静态RAM但大小固定不会造成栈溢出。例如按下面这种方式封装/* 全局上下文避免栈空间被大量占用 */ static MD5_CTX g_md5_ctx; int md5_calc(const uint8_t *data, uint32_t len, uint8_t digest[16]) { if (data 0 || digest 0) { return -1; } MD5_Init(g_md5_ctx); MD5_Update(g_md5_ctx, data, len); MD5_Final(digest, g_md5_ctx); return 0; }这种写法有一个前提同一时间内只能有一个计算流程使用这个全局ctx。如果系统里多个任务会同时算摘要每个任务必须有自己的ctx或者用互斥锁包住整个计算过程。否则两个任务交替调用缓冲区互相盖摘要必然错。第二减少临时缓冲。如果数据已经在DMA缓冲区里直接把指针传给MD5_Update不要再拷贝到另一个整齐数组。MD5_Update内部本来就要拷贝到自己64字节buffer调用方再拷贝一次就是浪费。第三把常量表放到只读数据段。C语言里用const uint32_t T[64]定义编译器通常会把常量放到Flash的只读区。如果编译器还是把它放到RAM需要检查链接脚本把该段定位到Flash的.rodata区域。由于单片机执行代码时一般可以只读访问Flash这样MD5模块的RAM占用就只有全局上下文加少量局部变量几乎没有额外开销。4. 单片机MD5常见问题与避坑排查从摘要不对到系统复位4.1 现象一摘要结果和PC端不一致短数据能对上长数据对不上现象算abc这类短字符串结果和标准摘要一致换成几百字节的数组结果就开始变甚至每次复位结果都不一样。原因最常见的是长度参数传错。strlen遇到字符串中间的0x00会提前截断而MD5要求计算所有字节另一种是把sizeof(指针)当作数组长度结果只算了4或8字节。还有一种是数据源本身有符号扩展问题把int8_t负值传给uint8_t参数字节内容被改动。解决核对所有调用MD5_Update的地方确认长度是从接口层得到的字节计数而不是从字符串函数推断。测试时故意构造一个包含0x00、0xFF的配置块和PC上对同一份二进制文件计算的结果比对。如果还不一致在MD5_Final前把原始输入字节通过串口回传在PC端人工比较是数据传错还是算法算错。4.2 现象二在中断服务函数里调用MD5_Update系统卡死或行为异常现象在UART接收中断或定时器中断里直接调用MD5_Update中断处理时间变长主循环响应迟钝严重时看门狗复位。原因MD5_Update不是一条指令级别的短计算。在常见32位单片机上一个块压缩要执行几百条指令在8位机上可能上千条。中断里做这种耗时操作会拉高系统响应延迟如果中断优先级更高还会压掉其他更紧急的中断处理。解决把MD5计算从ISR里挪出来。常见做法是ISR只把接收到的数据放进环形缓冲区置一个事件标志主循环或专用任务发现标志后调用MD5_Update。如果一定要在中断上下文算需要先关掉所有可被抢占的中断保证计算期间不被其他ISR打断但这是牺牲实时性换来的我只建议在计算量很小的场景使用。4.3 现象三RAM不足或栈溢出MD5跑着跑着数据被踩现象初始化MD5时一切正常跑几次摘要后某个全局变量无故改变或者调用MD5_Final时进入硬件异常。原因经典MD5实现里MD5_Update内部会声明一个16个uint32_t的数组用于存放当前块的16个输入字这就要64字节本地变量。再加上函数嵌套调用一次MD5_Update在栈上可能需要100字节以上。如果任务栈只分配了256字节就很容易溢出。解决第一步给MD5调用所在的任务加栈至少增加256到512字节第二步把上下文结构体和输入字数组改成静态或全局减少栈压力。如果已经用全局ctx直接看任务栈剩余空间。编译器开了-fstack-usage后会生成每个函数的栈使用量分析可以借此找到最大栈开销的函数比盲猜快很多。4.4 现象四MD5计算耗时太长实时任务出现周期性抖动现象项目主循环周期原本是几毫秒加入MD5后变成几十毫秒或者某个周期性任务抖动明显。原因每次MD5_Update调用都要做数据搬运和可能的块压缩。如果每收到1字节就调一次MD5_Update函数调用开销和循环开销会占主导反而比攒够64字节一次计算慢得多。解决调整调用策略。在采集线程里先把数据累积到自己的缓冲区攒到至少512字节再一次性调用MD5_Update。如果业务上必须边收边算也要保证每次调用至少传入几十字节。另一个处理是降低计算频率如果只是偶发货校验用完全没必要每周期都算。4.5 现象五用MD5做防篡改结果数据被改了也验不出来现象固件被恶意替换后MD5摘要竟然和原始固件一致校验流程放行了。原因MD5碰撞攻击在业界已经很成熟。攻击者可以构造一个碰撞块插到数据前面让整个文件的MD5摘要和原版一致。对量产设备升级来说单靠MD5容易被绕过。解决在MD5基础上加盐。把一段设备固定的密钥和固件内容混合后再计算相当于一个简化版HMAC-MD5攻击者不知道盐值就无法预构造碰撞。更稳妥的方案是换用SHA-256或国产SM3主流32位单片机上计算速度也可接受。如果项目限制必须用MD5至少要加长盐值和版本号并配合签名算法做固件认证。5. 进阶用法用MD5给固件升级加一道带盐的完整性校验有了前面的基础最后给一个实用方案在bootloader里用MD5校验固件并且加上盐防简单篡改。这个方案我在多个模拟项目里检验过不依赖外部加密芯片只用单片机自身Flash和RAM就能完成。先定流程上位机把待升级固件切块写入Flash同时计算一个带盐摘要。盐值是设备固定的4字节ID比如0xA5、0x5A、0x00、0x01。计算时把固件所有字节和盐值拼成数据流取MD5。bootloader收完固件并写入Flash后再从Flash里按相同顺序读出所有字节加上盐值计算摘要和固件头里存放的摘要比对一致才跳转到新固件。这里的关键是盐值怎么放。我一般把盐值放在固件文件的末尾而不是头部。因为bootloader解析固件头时通常不认识自定义扩展字段把盐值作为数据流的最后几个字节两边规则都写成先算固件全文再算盐值代码最简单。/* bootloader内的固件完整性校验函数 */ uint8_t boot_check_firmware(void) { MD5_CTX ctx; uint8_t digest[16]; uint8_t salt[] {0xA5, 0x5A, 0x00, 0x01}; uint32_t offset APP_START_ADDR; uint32_t app_size get_app_size_from_header(APP_START_ADDR); if (app_size 0 || app_size APP_MAX_SIZE) { return 0; } MD5_Init(ctx); while (offset APP_START_ADDR app_size) { uint32_t chunk_len (offset 512 APP_START_ADDR app_size) ? 512 : (APP_START_ADDR app_size - offset); uint8_t buf[512]; read_flash(buf, offset, chunk_len); MD5_Update(ctx, buf, chunk_len); offset chunk_len; } MD5_Update(ctx, salt, sizeof(salt)); MD5_Final(digest, ctx); return compare_digest_with_header(digest, APP_START_ADDR); }代码里read_flash是从Flash读数据到RAM缓冲注意512字节的局部数组在栈上如果bootloader栈不够把这个数组改成静态。compare_digest_with_header从固件头的固定偏移读出期望摘要逐字节比较。盐值必须和上位机生成工具里保持一致否则两边算出来的摘要永远对不上。还需要注意一个细节固件文件本身可以不包含盐值盐值作为追加块参与摘要计算。这样应用固件不需要知道自己被加盐bootloader和上位机各持一份相同常量即可。以后如果换盐改上位机和bootloader各自的一份常量就行不动应用结构。最后提醒验证时一定要真的在应用里改一个字节确认bootloader能拒绝启动而不是只比对上位机生成的摘要。我之前就是只测了数据包摘要没测bootloader这段Flash读取结果一个偏移写错直到样机升级后无法启动才排查出来。固化这个习惯之后固件升级校验才真正稳定。希望这篇带盐方案能帮你少走一步弯路。本文还有配套的精品资源点击获取

相关新闻

Delphi转C# 4.0迁移实战:类型映射、工具选型与避坑指南

Delphi转C# 4.0迁移实战:类型映射、工具选型与避坑指南

简介:Delphi2CS 4.0 是一款将 Delphi 代码转换为 C# 代码的实用工具,主要面向需要做旧项目迁移、跨语言重构的开发者,尤其适合手上积累了大量 Delphi 源码、希望低成本转向 .NET 技术栈的中高级程序员。该版本在原有基础上做了关键调整&#…

2026/10/16 20:18:47 阅读更多 →
Spring AI Alibaba停更后Java AI集成重构指南

Spring AI Alibaba停更后Java AI集成重构指南

1. 项目概述:当一个生态组件悄然退场,开发者真正该焦虑的是什么? “Spring AI Alibaba已停更了,Java还有希望吗?”——这句话最近在几个技术社区里反复刷屏,语气里带着点调侃,又透着真实的困惑…

2026/10/16 20:17:47 阅读更多 →
开源命令行AI编程助手 free-claude-code 实战指南

开源命令行AI编程助手 free-claude-code 实战指南

最近把 free-claude-code 引入到日常开发流程之后,我才意识到:过去那些让我心烦的重复劳动,其实可以被一个命令行工具消化掉大半。free-claude-code 是一个开源、免费、注重本地可控性的交互式编码助手。它跟常见的网页聊天式写代码工具不同&…

2026/10/16 20:17:47 阅读更多 →

最新新闻

PyTorch模型跨框架部署:ONNX转TensorFlow实战与避坑指南

PyTorch模型跨框架部署:ONNX转TensorFlow实战与避坑指南

/* 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 3:44:56 阅读更多 →
低成本AI短剧制作全流程:0.02元/秒成本控制与实操指南

低成本AI短剧制作全流程:0.02元/秒成本控制与实操指南

1. 低成本AI短剧的底层逻辑与方案选型1.1 为什么0.02元/秒这个数字值得认真对待第一次看到“0.02元/秒”这个报价的时候,我的反应跟大多数人一样:要么是引流噱头,要么就是有什么隐藏的坑。但实际跑完整个流程之后,我发现这个数字在…

2026/10/17 3:44:56 阅读更多 →
CentOS yum源报错排查:修复Cannot find valid baseurl的三种方案

CentOS yum源报错排查:修复Cannot find valid baseurl的三种方案

CentOS 的 yum 源报错,大概是 Linux 运维里出现频率最高的一类问题了。尤其是Cannot find a valid baseurl for repo: base这句,几乎每个用过 CentOS 7 的人都见过。我最近在整理一批退役虚拟机时又踩了一遍,处理过程中翻了不少资料&#xff…

2026/10/17 3:44:56 阅读更多 →
从零到发布:用TaoToken辅助完成VSCode插件开发全流程

从零到发布:用TaoToken辅助完成VSCode插件开发全流程

/* 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 3:44:56 阅读更多 →
hustoj源码深度解析:工业级在线判题系统架构与沙箱实现

hustoj源码深度解析:工业级在线判题系统架构与沙箱实现

简介:本资源为华中科技大学HUSTOJ在线评测系统最新源码(r2133版本),专为ACM/ICPC程序设计竞赛训练与教学场景设计,适用于高校算法教练、竞赛集训队及有自建OJ需求的开发者。压缩包共2000个文件,主体包含281…

2026/10/17 3:44:56 阅读更多 →
AI仿真凭什么敢信?代理模型原理、可信度验证与工程应用边界解析

AI仿真凭什么敢信?代理模型原理、可信度验证与工程应用边界解析

前阵子有位做结构设计的同行问我:AI仿真秒级出结果,你敢拿它直接下设计结论吗?这个问题问到了点子上。AI仿真这几年已经从“玩票”变成了CAE圈子里的热门话题,各家厂商都在推“实时仿真”“AI代理模型”“零阶降阶”的概念。但工程…

2026/10/17 3:43:56 阅读更多 →

日新闻

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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →