从一机一密到ACL:EMQX+Spring Boot构建物联网设备接入双重安全防线
说实话第一次亲眼看到别人用我平台上另一台设备的连接参数伪造了一整条温度变化曲线打到我后台时我后背是发凉的。数据告警、联动逻辑、历史存储全部被误导最可怕的是平台侧看起来一切正常设备在线、数据频率稳定、格式完全合法。后来复盘才发现接入层只用了“固定账号密码”设备之间没有任何隔离拿到一份连接参数就能冒充任意设备上报数据。这就是物联网平台安全里最常见的“裸奔”状态。今天我把在 Spring Boot EMQX 上落地的一机一密认证和 ACL 权限控制完整拆开讲一遍从原理到代码再到上线之后的坑一次讲清楚。这套方案解决的核心问题就两个设备身份能不能被伪造以及设备连接上来之后能不能越权访问别人的主题。1. 设备伪造问题的本质与物联网安全的两道门1.1 为什么固定密码的设备身份一捅就破早期很多物联网平台的接入逻辑非常简单设备出厂时写死一组 MQTT 连接参数比如clientIddevice_001、usernamedevice_001、password123456。平台侧只要在 EMQX 里配置一个全局用户名密码或者按用户名列表做静态校验就认为“连上来的是合法设备”。问题在于MQTT 连接过程本身不加密的话抓包工具非常容易就能拿到客户端发上来的报文clientId、username、password 直接是明文可见的。就算启用了 TLS设备端固件被逆向的情况也时有发生——固件里写死的连接凭据、服务器地址、产品密钥全都会被翻出来。攻击者拿到这些参数后完全不需要懂底层协议写一个几十行的 MQTT 客户端脚本改一下 clientId就能模拟任意设备接入平台上报假数据、下发假指令。更隐蔽的是很多固定密码是“一码多用”的。某个厂商为了出厂配置方便给同一批设备都设置了同一个密码甚至用户名都共用一个。一旦其中一台设备被逆向或者密码被泄露整条产品线的设备全部暴露。所谓“谁都能伪造别人的设备数据”本质上不是加密算法不够强而是身份模型太粗糙——平台根本没有把每一台设备当成独立、可撤销的个体。1.2 一机一密和 ACL 到底解决了什么既然固定密码不可靠第一步自然是让每台设备拥有独立的、动态的凭据这就是“一机一密”每一台设备在出厂或注册时分配一个唯一 clientId 和一个只有平台和设备自己知道的 secret 密钥连接时用这个密钥结合时间戳生成动态签名密码。这样就算抓包拿到了当前这次连接的密码也无法推算下一次的密码因为签名里带了时间因子就算拿到了某个设备的密钥也只会影响这一台设备可以在平台上单独吊销它而不是整个产品线一起停摆。但“一机一密”只解决了“你是谁”的问题。设备连上之后它还能干什么、能访问哪些主题这是第二道门ACL 权限控制。MQTT 协议里设备通过发布publish和订阅subscribe主题来交换数据。如果不加限制一台认证通过的水表设备完全有权限去订阅另一台电表的主题或者向控制台主题发布指令。ACL 就是在发布和订阅这两个动作发生时根据设备身份、目标主题、动作类型来决定允许还是拒绝。两道门的关系可以这么理解一机一密是门禁卡证明你是公司员工ACL 是工位权限告诉你只能进自己的工位不能去财务室翻账本。物联网平台里这两者缺一不可只认证不授权内部横向越权问题依旧存在。1.3 典型攻击路径与防护效果可以把一次常见攻击拆解成几步来对照攻击者从设备固件或抓包获取 MQTT 连接信息。使用获取到的 clientId 和密码连接 EMQX。连接成功后尝试订阅通配主题比如#或devices//data。如果订阅成功开始批量接收其他设备的数据。伪造某个设备向平台发送指令或上报业务数据。引入一机一密后第 2 步会因为动态密码校验失败而被阻断除非攻击者同时拿到了当前时间戳和 secret 密钥并且算出了正确签名。引入 ACL 后即使前几步被突破比如设备密钥被泄露第 3 步也会被拒绝因为业务主题权限被限定在/devices/{clientId}/...范围内通配订阅拿不到数据。第 5 步同理ACL 会拦截向非授权主题发布消息的请求。2. 技术方案选型为什么用 EMQX Spring Boot2.1 EMQX 在设备接入层的优势选 EMQX 做 MQTT Broker不是因为它名字好听是因为它把“认证”和“ACL”都做成了可插拔的机制。EMQX 支持内置数据库认证、Redis 认证、HTTP 认证、JWT 认证等多种方式ACL 也支持静态规则、HTTP 查询、Redis 查询等。这意味着我们不需要改 EMQX 源码只需要按约定实现一个 REST APIEMQX 就会在设备连接时、发布消息时、订阅主题时回调我们的服务根据返回结果决定放行还是拒绝。EMQX 本身的性能也适合物联网场景。单节点可以支撑几十万甚至上百万连接集群横向扩展方便连接层、消息层分离得比较清楚。对于我们这种还要自己写业务后端的小团队来说用 EMQX 比自行实现 MQTT 协议栈要靠谱得多。那有人会问直接改 EMQX 配置文件录入每个设备的用户名密码不也能做一机一密吗可以但极难维护。设备数量上千上万之后每次设备新增、吊销、密钥轮换都要改配置、重载、甚至重启根本无法自动化。所以更好的做法是让 EMQX 把认证判断“外包”给我们的 Spring Boot 服务由数据库动态管理设备凭据。2.2 Spring Boot 作为认证中心的价值Spring Boot 在物联网平台里通常负责设备管理、数据存储、业务 API 这些事。既然设备注册、密钥下发、状态管理本来就在 Spring Boot 里做那把认证和 ACL 的判定逻辑也放到同一套系统顺理成章。这样做的核心好处是数据一致。设备注册后spring boot 数据库里立即有了这台设备的 clientId 和 secret设备连接时EMQX 把 clientId 和动态密码抛给 Spring BootSpring Boot 从库里查出该设备的密钥用同样的签名算法重新计算匹配通过就返回允许。整个流程不需要手动同步任何配置文件。另一个好处是便于扩展。以后如果要把认证逻辑从“HMAC 签名”升级为“双向 TLS 证书”或者接入第三方设备管理平台改动只发生在 Spring Boot 这一个服务里EMQX 侧的 HTTP 认证配置基本不用动。访问控制策略也一样ACL 规则可以做成数据库表后台管理界面直接增删改查而不是去改 EMQX 配置。2.3 整体架构与一次连接的完整链路整套方案的架构并不复杂主要角色有三个设备端持有 clientId 与 secret连接 EMQX 前动态生成密码。EMQXMQTT Broker负责接受设备连接和消息路由在关键动作发生时回调认证服务。Spring Boot 认证中心提供两个 HTTP 接口一个处理连接认证一个处理 ACL 校验。一次正常的设备连接流程如下设备向 EMQX 发起 MQTT 连接请求携带 clientId、username、password其中 password 是时间戳.签名的格式。EMQX 暂停握手使用 HTTP 认证器向 Spring Boot 的/emqx/auth接口发送认证请求。Spring Boot 从数据库查出该 clientId 对应的 secret校验签名和时间窗口返回allow或deny。如果返回 allowEMQX 继续完成 MQTT 握手设备成功接入。设备后续做 pub/sub 时EMQX 再向 Spring Boot 的/emqx/acl接口发送鉴权请求包含 clientId、主题、动作类型。Spring Boot 按设备拥有的主题权限判断返回 allow 或 denyEMQX 根据结果放行或拒绝该消息。这套链路里 EMQX 只做“执行者”具体“怎么判断”全部由我们自己的服务控制。这也是我推荐的做法认证逻辑留在业务端基础设施只负责执行策略。3. 一机一密认证的完整实现3.1 设备身份与密钥规划先确定设备在平台里的唯一标识也就是 MQTT 的 clientId。我建议直接使用业务侧的设备编码比如柔性序列号而不是用户自定义的备注名。这样在调日志、同步配置时clientId 可以直接对应到具体设备。密钥这块设备注册时由平台生成推荐使用至少 32 字节的随机字符串比如a1b2c3d4e5f60718293a4b5c6d7e8f90。密钥要同时存储在 Spring Boot 的设备表里并且通过安全渠道下发到设备端比如出厂烧录、设备配网阶段的加密传输。设备侧生成动态密码的算法我用的是 HMAC-SHA256签名原文可以自己定义规范关键是要平台端和设备端保持一致。我这里定的规则是密码格式{时间戳毫秒}.{HMAC_SHA256(secret, 时间戳毫秒 : clientId)}时间戳用毫秒级防止密码在一秒内被重用。3.2 Spring Boot 编写认证接口认证接口的核心逻辑分三步查设备、验签名、返回结果。直接看代码。RestController public class EmqxAuthController { Autowired private DeviceService deviceService; PostMapping(/emqx/auth) public ResponseEntityMapString, Object auth(RequestBody EmqxAuthRequest request) { String clientId request.getClientid(); String password request.getPassword(); // 1. 设备是否存在、是否启用 Device device deviceService.findByClientId(clientId); if (device null || !device.getEnabled()) { return deny(); } // 2. 密码格式需要是timestamp.sign String[] parts password.split(\\.); if (parts.length ! 2) { return deny(); } long timestamp; try { timestamp Long.parseLong(parts[0]); } catch (NumberFormatException e) { return deny(); } // 3. 时间窗口校验允许前后 5 分钟误差 long now System.currentTimeMillis(); if (Math.abs(now - timestamp) 5 * 60 * 1000L) { return deny(); } // 4. 重新计算签名并比较 String expectedSign HmacUtils.hmacSha256( device.getSecret(), timestamp : clientId ); if (!constantTimeEquals(expectedSign, parts[1])) { return deny(); } // 5. 返回 EMQX 要求的成功格式 MapString, Object result new HashMap(); result.put(result, allow); result.put(is_superuser, false); return ResponseEntity.ok(result); } private ResponseEntityMapString, Object deny() { MapString, Object result new HashMap(); result.put(result, deny); return ResponseEntity.status(401).body(result); } private boolean constantTimeEquals(String a, String b) { if (a.length() ! b.length()) { return false; } int result 0; for (int i 0; i a.length(); i) { result | a.charAt(i) ^ b.charAt(i); } return result 0; } }这里有几个细节值得强调。时间戳比较一定用Math.abs因为设备端时钟可能快也可能慢。签名比较不要用equals避免时间侧信道攻击上面用的常量时间比较是常规做法。返回的is_superuser字段对应 EMQX 的超级用户标识如果普通设备不需要绕过 ACL就固定设成 false。对应 EMQX 的请求体里会带clientid、username、password这些字段我们新增一个简单 DTO 接住即可。Spring Boot 的 Controller 不需要做什么额外的配置确保这个接口可以被 EMQX 所在网络访问到就好。3.3 客户端如何生成动态密码设备端的代码不太适合直接用 Java 写死在单片机里但签名逻辑本身足够简单。我先给一段脚本用于调试和模拟设备测试。import hmac import hashlib import time def make_password(secret, client_id): ts int(time.time() * 1000) msg f{ts}:{client_id} sign hmac.new(secret.encode(), msg.encode(), hashlib.sha256).hexdigest() return f{ts}.{sign} client_id device_001 secret a1b2c3d4e5f60718293a4b5c6d7e8f90 password make_password(secret, client_id) print(password)重点说明一下签名原文的格式是时间戳:clientId冒号是分隔符。设备和平台的代码里都必须保持完全一致哪怕差一个空格也会验不过。很多刚开始做一机一密的同学会在这里踩坑——平台签名代码里timestamp : clientId和客户端f{ts}:{client_id}看起来一样但如果有设备侧不小心带了换行符就会导致签名不稳定。建议在一开始就把签名规则写进接口文档里并给设备端 SDK 做单元测试向量固定 secret 和 timestamp验证输出签名是否一致。3.4 EMQX 配置 HTTP 认证的操作记录我用的是 EMQX 5.x在 Dashboard 里配置 HTTP 认证器非常直观。登录 EMQX 控制台后依次进入“管理工具”-“认证”点击“创建认证器”选择“HTTP”。配置要点如下认证请求 URL填http://你的SpringBoot服务地址:8080/emqx/auth请求方法POST请求头Content-Type: application/json请求体模板EMQX 支持占位符例如{ clientid: ${clientid}, username: ${username}, password: ${password} }认证成功判定HTTP 状态码 200认证失败判定HTTP 状态码 401在 EMQX 4.x 里做法略有不同需要修改emqx_auth_http.conf配置文件把auth.http.auth_req.url指到我们的认证接口然后 reload 插件。核心逻辑是一样的只是配置方式从界面变成了文件。这里也回应一个常见问题“EMQX 上怎么添加账号密码”。如果你只是临时调试可以在认证里创建一个“内置数据库”认证器然后在用户管理页面手动添加用户名密码。这种方式适合验证 MQTT 客户端是否正常但不适合生产环境的一机一密因为每个设备都要手动录入、手动吊销效率太低。生产环境要做的就是把认证器切换成 HTTP让平台侧动态决定每个 clientId 和密码的合法性。3.5 吊销设备与密钥轮换一机一密真正做到位还得有快速的吊销手段。设备密钥泄露、设备报废、用户退订都需要马上让这台设备失去连接能力。实现上很简单认证接口里第一步就是查设备状态设备表中的enabled字段置为 false那么下一次设备连接就会在“设备是否存在、是否启用”处被拒绝。密钥轮换也不难平台生成新的 secret 更新到设备表即可。但设备端要处理“当前密钥已过期”的情况通常有两种思路一种是在配置阶段同步下发新密钥另一种是允许设备用旧密钥认证后通过一个特殊的管理主题获取新密钥下一次连接使用新密钥。第二种方案会更复杂需要设计单独的安全下发流程。我这里直接把第一种场景做好已经能覆盖绝大多数业务诉求。4. ACL 权限控制精细化主题访问管理4.1 认证通过不等于可以到处看别人的数据只做一机一密设备能连上 EMQX但它能订阅哪些主题完全取决于 EMQX 的默认设置。如果不配 ACLEMQX 通常会允许认证通过的客户端订阅任意主题包括#这种通配符。这意味着一台设备可以监听平台上所有设备上报的数据甚至可以向控制指令主题里塞消息这比伪造单台设备还严重。ACL 的价值在于把设备的“可见范围”和“操作范围”钉死。生产环境里我通常把主题设计成带设备维度的结构。下面是一套示例数据上报devices/{clientId}/data事件上报devices/{clientId}/event平台指令下发devices/{clientId}/cmd每台设备只能向属于自己clientId的主题下发布消息也只能订阅属于自己clientId的指令主题。设备 A 永远不会订阅到设备 B 的devices/B/data因为 ACL 接口会拦截。4.2 EMQX 的 ACL 模型与 HTTP ACL 配置EMQX 的 ACL 默认支持多条来源包括内置规则、文件、HTTP 查询。我们需要的是动态查询所以在 Dashboard 的“授权”里创建“HTTP”授权器。配置要点和认证器类似URLhttp://你的SpringBoot服务地址:8080/emqx/acl方法POST请求体模板{ clientid: ${clientid}, username: ${username}, topic: ${topic}, action: ${action} }允许判定HTTP 200 且 body 里resultallow拒绝判定HTTP 401 或 body 里resultdeny这里${action}的取值通常是publish或subscribe。EMQX 在客户端做发布操作时会带着目标主题来查询 ACL做订阅操作时也会带着要订阅的主题来查询。我们需要在 Spring Boot 里分别判断。4.3 Spring Boot 实现 ACL 授权接口ACL 接口的业务逻辑比认证接口更灵活建议先做成“可配置的规则表”而不是在代码里写死。这里给一个基于前缀判断的示例版本RestController public class EmqxAclController { PostMapping(/emqx/acl) public ResponseEntityMapString, Object acl(RequestBody EmqxAclRequest request) { String clientId request.getClientid(); String topic request.getTopic(); String action request.getAction(); // 主题前缀必须是 /devices/{clientId} String dataTopicPrefix /devices/ clientId; if (!topic.startsWith(dataTopicPrefix)) { return deny(); } // 发布数据只允许发到 data 和 event 主题 if (publish.equals(action)) { if (topic.equals(dataTopicPrefix /data) || topic.equals(dataTopicPrefix /event)) { return allow(); } } // 订阅只允许监听 cmd 主题 if (subscribe.equals(action)) { if (topic.equals(dataTopicPrefix /cmd)) { return allow(); } } return deny(); } private ResponseEntityMapString, Object allow() { MapString, Object result new HashMap(); result.put(result, allow); return ResponseEntity.ok(result); } private ResponseEntityMapString, Object deny() { MapString, Object result new HashMap(); result.put(result, deny); return ResponseEntity.status(401).body(result); } }生产环境里我不会把规则直接写死在代码里而是建一张device_topic_rule表字段包括设备分组、允许的主题前缀、允许的动作等。ACL 接口从数据库加载规则再跟请求里的 clientId、topic、action 匹配。这样后台可以随时调整某类设备的访问范围不用发版。4.4 主题设计与权限粒度的一些建议主题设计直接决定 ACL 规则的复杂度我踩过的坑就是一开始把主题层级设计得太粗比如只分data/up、data/down设备间无法隔离不得已只能靠 ACL 代码里加一堆if。后来改成“设备ID 作为主题第二层”规则就变得非常工整。如果你的业务还涉及设备分组比如一个用户拥有多个设备或者一个项目组共享主题建议把主题设计成groups/{groupId}/devices/{deviceId}/datagroups/{groupId}/devices/{deviceId}/cmdACL 规则里再增加一层“用户-设备-分组”的映射关系。其实无论层级怎么设计ACL 判断的核心就一句话这个人或这台设备对当前这个主题这个动作有没有被明确授权。没有匹配到放行规则的默认拒绝。5. 实战中的踩坑记录与性能优化5.1 认证服务一旦挂了所有设备连接全部失败这是最容易被忽略的问题。认证和 ACL 接口是 EMQX 的正常链路中强制调用的外部服务如果 Spring Boot 宕机EMQX 无法拿到认证结果会直接拒绝设备连接线上全部设备瞬间掉线。生产环境必须做三件事Spring Boot 认证服务自身要部署成多实例前面加负载均衡。EMQX 侧配置合理的请求超时时间避免设备连接被长时间挂起。考虑降级策略如果是短时故障是否允许设备继续连接一段时间这个需要和业务风险权衡从安全角度我不建议无脑降级但至少要保证监控告警能第一时间发现认证接口异常。我在实际运维中给认证接口加了独立健康检查每分钟探测一次探测失败直接告警。另外Redis 缓存认证结果可以缓解部分突发流量但如果认证服务整体不可用缓存也只能救“已经在缓存里”的设备新设备依然起不来。5.2 高并发连接时认证接口的瓶颈一批设备同时上电瞬间可能会产生几千甚至几万个并发连接。EMQX 会同时发大量 HTTP 请求到 Spring Boot如果每个请求都查一次数据库数据库很容易被打满。优化思路有几个在 Spring Boot 里给设备密钥加本地缓存比如 Caffeine缓存 key 是 clientIdvalue 是设备实体过期时间 5 到 10 分钟。设备重连时直接命中缓存减少查库压力。认证结果的校验是 CPU 密集的 HMAC 计算量上来之后可以用更宽松的超时时间比如 5 分钟窗口来降低频率。对同一 clientId 的并发认证请求做防抖如果已经有一个正在处理的认证请求后续请求可以复用结果。设备连接本身也可以做错峰。物联网平台如果支持设备端随机延迟上线对后端是巨大的友善这个优化通常和设备固件一起配合平台侧也可以在认证接口里做限流保护。5.3 设备时间不准导致签名验不过一机一密依赖时间戳做新鲜度校验但很多物联网设备为了省电用的晶振精度不高或者常年断电之后 RTC 偏差很大。如果设备时间比服务器慢了十分钟签名验算时Math.abs(now - timestamp)就超过了窗口平台会唯一拒绝。在真实项目中我遇到最多的问题就是这个。一个稳妥的做法是把时间窗口放宽到 10 分钟同时在设备配网阶段从平台同步一次网络时间。如果设备本身有 NTP 对时能力更好。签名规则里的时间戳也可以考虑用“当前时间所在的小时数 随机数”牺牲一些重放防护强度来换容错性但这需要根据业务场景权衡。5.4 ACL 规则缓存导致权限变更不生效ACL 接口调用频率比认证高每条 pub/sub 消息都可能触发一次。为了性能我在 Spring Boot 里加了缓存把 clientId 对应的主题规则缓存起来。但是这里有个坑设备被禁用了或者设备要换绑用户了ACL 接口还在返回缓存里的旧规则设备依然可以访问旧主题。要解决这个问题就得在规则变更时主动失效缓存。最简单的方案是引入 RedisACL 查询先走 Redis规则变更时删除对应 clientId 的缓存 key。如果不想引入新组件可以在 Spring Boot 里维护一个进程内缓存并提供一个内部通知接口后台对规则做变更时调用该接口刷新本机缓存。多实例部署时进程内缓存需要广播刷新会麻烦一点有条件还是直接上 Redis。5.5 常见问题速查表现象可能原因解决思路设备一直连接失败EMQX 日志提示认证失败签名算法不一致 / 密钥错误 / 时间戳超时先用脚本单独算签名与平台端比对检查设备时钟偶尔连接失败重启后又正常时间戳处于窗口边界把时间窗口加大或客户端在连接前对时设备能连接但发布消息超时或被拒绝ACL 接口返回 deny检查主题前缀是否匹配设备 clientId检查 publish 动作的规则设备能发布到别人的主题ACL 接口未启用 / 返回逻辑漏洞确认 EMQX 授权器是 HTTP 模式检查前缀判断是否完整认证接口压力大数据库被打满每次连接都查库加 Caffeine 本地缓存错峰上线设备吊销后仍然能连接认证结果被缓存检查缓存策略吊销时主动删除该设备缓存5.6 安全增强的后续方向一机一密 ACL 是物联网平台安全的基础门禁基础不等于全部。我在这个基础上还会叠加这些能力连接启用 TLS避免签名密码在传输中被截获。定期轮换设备的 secret 密钥至少每年一次。对高频异常连接行为做检测比如同一 clientId 频繁断开重连或者同一个 IP 下大量不同 clientId 连接触发风控策略。对设备上报数据做业务层校验防止伪造数据本身。即使身份合法也不代表数据是真实采集的这个需要业务侧做量程、变化率、一致性检测。如果项目预算允许可以考虑把认证升级为双向 TLS 证书方案设备内置证书EMQX 和证书签发服务配合做到硬件级身份绑定。但一机一密作为成本低、接入快的方案仍然是绝大多数物联网平台的首选。最后说说我的真实体感。这套方案我从一开始的 Demo 做到线上大概花了两周整个过程中最大的阻力不是代码而是“统一签名规则”这件事。平台端、网关端、设备端各写各的时间戳格式、分隔符、密钥编码稍有不同就会折腾半天。所以如果你准备动手建议第一天就把签名规范钉死并且做一版测试向量给定相同的 secret 和时间戳要求所有端必须输出相同的签名串。这个工作做完后面就会顺畅很多。另外别忘记给认证和 ACL 接口加上监控它们的稳定性直接决定你线上设备能不能连得上、数据能不能正常走这比任何业务接口都重要。

相关新闻

2026 Agent 开发实战手册:从架构、记忆到并发与安全的工程化落地

2026 Agent 开发实战手册:从架构、记忆到并发与安全的工程化落地

1. 这份报告到底在聊什么2026 年的 Agent 开发者调研报告,加上 Alibaba Cloud 的 AI Agent Handbook,这两个东西放在一起看,其实指向的是同一件事:Agent 开发这件事,已经从“能不能跑起来”进入到了“怎么跑得稳、跑得…

2026/10/9 1:58:18 阅读更多 →
EI_策略训练_Isaac sim

EI_策略训练_Isaac sim

Isaac Gym 本身不是动作采集(motion capture)框架,而是一个基于 GPU 加速的强化学习仿真训练平台。但它在利用动作数据(如 MoCap 录制的行走、跑跳等)来训练机器人运动控制策略方面具有显著优势,因此常被用…

2026/10/9 1:58:18 阅读更多 →
IL_动作捕捉和模仿学习

IL_动作捕捉和模仿学习

IL:Imitation Learning 实际机器人动作采集和策略训练中,完全可以将 CSV 文件(动作数据) 机器人模型 XML 文件(如 URDF、MJCF 或 MuJoCo XML)转换生成 .npz 文件,这是机器人模仿学习&#xff0…

2026/10/9 1:58:18 阅读更多 →

最新新闻

SHA1算法的各种密码分析方法全面盘点

SHA1算法的各种密码分析方法全面盘点

SHA1算法的各种密码分析方法全面盘点SHA-1(安全散列算法1)是由NSA设计、NIST于1995年发布的160位密码杂凑函数。基于Merkle-Damgrd迭代结构,将任意长度消息分为512位块,通过压缩函数依次处理。理论上,SHA-1应具备160位…

2026/10/9 2:34:38 阅读更多 →
Python 数据挖掘实战项目:电商用户行为分析(聚类分群、流失预测与关联规则)

Python 数据挖掘实战项目:电商用户行为分析(聚类分群、流失预测与关联规则)

Python 数据挖掘实战项目:电商用户行为分析(聚类分群、流失预测与关联规则) 数据挖掘课程设计与竞赛入门的共同痛点是「没有真实数据可练」。本工程内置一个带真实行为规律的订单数据生成器(5000 用户 / 约 3 万条订单&#xff0…

2026/10/9 2:34:38 阅读更多 →
Java 异常处理实战案例集:50 个高频异常的现象、根因、修复与预防

Java 异常处理实战案例集:50 个高频异常的现象、根因、修复与预防

Java 异常处理实战案例集:50 个高频异常的现象、根因、修复与预防 异常处理是 Java 面试与答辩的必考题,但多数教程只讲语法不讲「为什么会炸」。这套案例集把 50 个高频异常按 8 大家族归类,每个案例固定四段式:现象&#xff08…

2026/10/9 2:34:38 阅读更多 →
SaaS「现金陷阱」全解析:EnterpriseCRM 案例教你如何识破 5:1 LTV:CAC 的假象(Product-Manager-Skills 实战拆解)

SaaS「现金陷阱」全解析:EnterpriseCRM 案例教你如何识破 5:1 LTV:CAC 的假象(Product-Manager-Skills 实战拆解)

AI 技能AI 插件 【免费下载链接】Product-Manager-Skills Product Management skills framework built on battle-tested methods for Claude Code, Cowork, Codex, and AI agents. 项目地址: https://gitcode.com/gh_mirrors/pr/Product-Manager-Skills 点击查看 免…

2026/10/9 2:34:38 阅读更多 →
互联网消费金融资金合作模式全解析:助贷、联合贷、ABS与信托通道选型指南

互联网消费金融资金合作模式全解析:助贷、联合贷、ABS与信托通道选型指南

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

2026/10/9 2:34:38 阅读更多 →
Loop 径向菜单窗口管理完整指南:按住一个键,窗口就去哪

Loop 径向菜单窗口管理完整指南:按住一个键,窗口就去哪

Loop 径向菜单窗口管理完整指南:按住一个键,窗口就去哪 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 手要拖窗口之前 光标悬在窗口标题栏上,手指刚要往下拽&#…

2026/10/9 2:33:38 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

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/8 15:26:32 阅读更多 →
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/8 15:26:40 阅读更多 →
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/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 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/8 21:13:17 阅读更多 →
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/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练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/7 13:34:55 阅读更多 →