news 2026/5/11 21:58:39

【Leona】BoxId 是什么-设备指纹参数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Leona】BoxId 是什么-设备指纹参数

BoxId 是什么?从Leona.sense()/v1/verdict的可落地闭环:签名、落库、错误处理与回归验证(基于公开示例)

TL;DR

  • BoxId 不是“风险结论”,而是一次“证据报告兑换券”:端上拿 BoxId,后端换证据报告
  • /v1/verdict(公开合约)是后端接口:必须用 SecretKey 签名请求;并明确标注为single-use,因此后端落库/缓存是硬要求
  • 公开仓库提供了多语言后端示例入口:examples/boxid-verdict/(Python/Java/Go/Node/C/C++)。本文把这些公开事实串成一条能直接照着做的最小闭环,并给出可复制的测试向量。

发布摘要

移动对抗安全的工程化落地,关键不是端上堆更多检测点,而是把链路做对:端上只上报证据并返回 BoxId;后端用 SecretKey + 请求签名调用/v1/verdict换证据报告并落库;业务策略在后端输出 allow/challenge/deny,并留下可审计的证据快照。本文只基于公开仓库内容(README +examples/boxid-verdict),讲清楚合约、签名、single-use 语义、落库结构、错误处理与回归验证。


0) 三条硬规则(违反任意一条都等于把系统送给攻击者)

  1. SecretKey 永远只在后端:客户端不允许持有,也不允许直接调用/v1/verdict
  2. BoxId 只做透传:端上不要基于本地结论做放行/拦截。
  3. 证据报告必须落库/缓存:因为/v1/verdict在公开 README 中明确标注为 single-use。

1) 端到端最小闭环(可以按这个顺序实现/验收)

  1. App:调用Leona.sense()上报证据 → 得到BoxId
  2. App → 业务后端:在登录/支付/发帖等请求里携带BoxId
  3. 业务后端 → Leona:POST /v1/verdict(SecretKey + 签名)换取证据报告
  4. 业务后端:落库/缓存证据报告(BoxId 单次消费)
  5. 业务后端:按分层策略输出动作(allow/challenge/deny)并审计

这条链路的本质是:把“最终决策出口”从 APK 移出,并把解释性与可治理性放到后端。


2)/v1/verdict公开合约(后端调用)

Endpoint:

  • POST https://leona.xiyanshan.com/v1/verdict

Body:

{"boxId":"01KR0000000000000000000000"}

Headers(后端构造):

  • Authorization: Bearer <LEONA_SECRET_KEY>
  • Content-Type: application/json
  • X-Leona-Timestamp: <unix-time-ms>
  • X-Leona-Nonce: <random-nonce>
  • X-Leona-Signature: <base64url-hmac-sha256>

签名算法(公开说明):

signingText = timestamp + "\n" + nonce + "\n" + sha256(requestBody) signature = base64url_no_padding(HMAC-SHA256(secretKey, signingText))

工程化解读:

  • nonce + timestamp防重放;body sha256防篡改。
  • 你应该把“timestamp 窗口错误 / nonce 重放 / 签名不匹配”当成可观测的失败类型记录到日志与指标(后面排障会省很多时间)。

3) 直接可用的多语言实现(来自公开仓库 examples)

下面代码片段来自公开仓库examples/boxid-verdict/,你可以用它们作为后端集成最小参考实现

3.1 Node.js(examples/boxid-verdict/nodejs/query_boxid.mjs

importcryptofrom"node:crypto";constbody=JSON.stringify({boxId});consttimestamp=Date.now().toString();constnonce=crypto.randomBytes(16).toString("base64url");constbodySha256=crypto.createHash("sha256").update(body).digest("hex");constsigningText=`${timestamp}\n${nonce}\n${bodySha256}`;constsignature=crypto.createHmac("sha256",secret).update(signingText).digest("base64url");

3.2 Python(examples/boxid-verdict/python/query_boxid.py

body=json.dumps({"boxId":box_id},separators=(",",":")).encode("utf-8")timestamp=str(int(time.time()*1000))nonce=base64url_no_padding(secrets.token_bytes(16))body_sha256=hashlib.sha256(body).hexdigest()signing_text=f"{timestamp}\n{nonce}\n{body_sha256}".encode("utf-8")signature=base64url_no_padding(hmac.new(secret.encode("utf-8"),signing_text,hashlib.sha256).digest())

3.3 Go(examples/boxid-verdict/go/query_boxid.go

body,_:=json.Marshal(map[string]string{"boxId":boxID})timestamp:=fmt.Sprintf("%d",time.Now().UnixMilli())nonce:=base64.RawURLEncoding.EncodeToString(randomBytes(16))bodyHash:=sha256.Sum256(body)signingText:=fmt.Sprintf("%s\n%s\n%s",timestamp,nonce,hex.EncodeToString(bodyHash[:]))signature:=base64.RawURLEncoding.EncodeToString(hmacSha256([]byte(secret),[]byte(signingText)))

说明:三种语言虽然写法不同,但签名输入字符串完全一致timestamp\nnonce\nsha256(body)


4) “验收级”测试:固定测试向量,先把签名实现锁死

很多集成问题不是“服务端不稳定”,而是签名实现细节不一致(JSON 是否有空格、是否 base64url、是否去 padding、timestamp 单位等)。

建议你先做一个“固定输入 → 固定输出”的单元测试,把签名实现锁死。

4.1 测试向量(可直接复制)

  • secretKey = "sk_test_123"
  • timestamp = "1700000000000"
  • nonce = "nonce_test"
  • body = {"boxId":"01KR0000000000000000000000"}(注意:JSON 必须无多余空格)

计算结果:

  • body_sha256_hex = 1d6530c70bc08d977158e83fb8fc5a11ef08490cabfdec17fa54f392e4754a45
  • signature_base64url = _Yjj8KhRfxMEnGaoRJrRKNtp_LOO2pNi2ndTzh9bLhs

4.2 Node.js 测试片段(示例)

importcryptofrom"node:crypto";functionsign(secret,timestamp,nonce,body){constbodySha256=crypto.createHash("sha256").update(body).digest("hex");constsigningText=`${timestamp}\n${nonce}\n${bodySha256}`;returncrypto.createHmac("sha256",secret).update(signingText).digest("base64url");}constbody='{"boxId":"01KR0000000000000000000000"}';constsig=sign("sk_test_123","1700000000000","nonce_test",body);if(sig!=="_Yjj8KhRfxMEnGaoRJrRKNtp_LOO2pNi2ndTzh9bLhs")thrownewError("signature mismatch");

只要这个测试过了,你再去联调线上接口,定位问题会简单很多。


5) single-use 语义:后端落库/缓存不是可选项

公开 README 明确:/v1/verdict是 single-use,成功查询会消费 BoxId。

这会直接影响你的业务实现:

  • 不要以“需要时再查一次”为前提;
  • 要把证据报告当成业务决策的一部分落库(并绑定业务 request/order/user)。

5.1 推荐最小落库字段(公开字段)

  • boxId
  • deviceFingerprint
  • canonicalDeviceId
  • events
  • authoritativeRiskTags/telemetryRiskTags
  • riskTagsBySource
  • provenancepolicyExplanation

5.2 最小 SQL 表结构(示例)

createtableleona_verdict_cache(box_idtextprimarykey,canonical_device_idtext,device_fingerprinttext,evidence_json jsonbnotnull,created_at timestamptznotnulldefaultnow(),business_user_idtext,business_request_idtext);

6) 错误处理与指标:把“集成”做成可运维的系统

建议你至少打这些指标:

  • /v1/verdict成功率、P95 延迟
  • 4xx/5xx 分布(尤其是签名类错误与窗口类错误)
  • 证据报告落库成功率
  • challenge 触发率/通过率(如果你有挑战)

日志建议:

  • 永远不要打印 SecretKey
  • 记录boxIdrequestIdstatuserror_typelatency_ms

7) 策略落地:一个务实的分层模板(配合公开字段)

不要把某个 tag 直接等价成封禁。一个能跑起来、也能承受误报的最小模板是:

  • authoritative 高信任证据命中 → challenge 或 deny(按业务风险分级)
  • 中性环境证据(模拟器/云机等)→ 结合业务上下文(新号/高价值更严)
  • telemetry 低信任证据 → 只用于解释/调试与回溯,不直接触发拦截

公开字段authoritativeRiskTagstelemetryRiskTags的分离,本质就是为了让你写出这种“可治理”的策略。


8) 你能从公开仓库得到哪些“可验证事实”(而不是空谈)

  • 合约事实:/v1/verdict的签名算法与 single-use 语义写在公开 README/示例里。
  • 示例事实:examples/boxid-verdict/提供多语言实现。
  • 边界事实:公开仓库反复强调“SDK 不做最终决策;后端自决”。

标签

  • BoxId
  • 后端集成
  • 请求签名
  • 证据落库
  • 风控策略

CTA

  • GitHub(欢迎 star):https://github.com/zedbully/leona-open
  • 项目主页:https://leona.xiyanshan.com/

9) 把“示例脚本”升级成“生产可用服务”:你真正要写的不是脚本,而是一个可运维的后端组件

公开仓库里的examples/boxid-verdict/很有价值:它把签名算法、请求头、body 哈希等关键细节写成了可运行代码。但在真实业务里,你不会在主业务进程里直接python query_boxid.py。你需要的是一个可复用、可观测、可回滚的“Leona 证据兑换组件”。

一个比较稳妥的做法是把它做成你后端内部的一个模块(或一个独立服务),并明确它的职责边界:

  • 输入:boxId+ 业务上下文(userId / requestId / riskTier 等)
  • 输出:证据报告(落库后返回 reportId 或摘要),以及策略动作(allow/challenge/deny)
  • 约束:任何情况下不泄漏 SecretKey,不把/v1/verdict暴露给客户端

下面给一个“够用但不复杂”的 Node.js(TypeScript 风格)示例,展示如何把脚本升级成服务。

9.1 组件划分(推荐)

  1. leonaClient:只负责签名与调用/v1/verdict
  2. verdictStore:只负责落库与幂等
  3. decisionEngine:只负责把 evidence report + businessCtx → decision
  4. api:只负责暴露内部接口给业务系统调用(绝不对外)

10) 生产级示例:实现一个“BoxId 兑换 + 落库 + 决策”内部 API

10.1 Express 路由(内部使用)

importexpressfrom"express";import{queryVerdict}from"./leonaClient";import{saveVerdictOnce,getCachedVerdictByBoxId}from"./verdictStore";import{decide}from"./decisionEngine";constapp=express();app.use(express.json());// 内部接口:业务后端调用(不要暴露公网)app.post("/internal/leona/exchange",async(req,res)=>{const{boxId,userId,requestId,isHighValue}=req.body;if(!boxId||!userId||!requestId)returnres.status(400).json({error:"missing fields"});// 1) 幂等:同一个 boxId 被重复请求时,先尝试从缓存/数据库读取constcached=awaitgetCachedVerdictByBoxId(boxId);if(cached){constdecision=decide(cached.report,{userId,requestId,isHighValue});returnres.json({source:"cache",decision,report:cached.reportSummary});}// 2) 兑换:调用 /v1/verdict 换取证据报告(single-use,务必尽快落库)constreport=awaitqueryVerdict(boxId);// 3) 落库:用 boxId 做唯一键,保证并发下不会写入两份awaitsaveVerdictOnce({boxId,userId,requestId,report});// 4) 决策:示例决策;真实业务一般要引入风控等级与灰度constdecision=decide(report,{userId,requestId,isHighValue});returnres.json({source:"live",decision,report:{boxId,canonicalDeviceId:report.canonicalDeviceId}});});app.listen(3000);

这个路由做了几件关键的“工程正确事情”:

  • 先查缓存/落库结果(幂等),再做兑换(避免重复消费 BoxId)
  • 兑换成功后立刻落库(single-use 语义要求)
  • 决策在后端做,且可以把isHighValue等业务上下文纳入

10.2leonaClient:严格复用公开签名算法

签名算法千万不要“凭感觉重写”,最好的方式是:

  • 直接以公开examples/boxid-verdict/nodejs/query_boxid.mjs为基准提取成函数
  • 再加上本文第 4 节的“固定测试向量”单测,锁死实现细节
importcryptofrom"node:crypto";constDEFAULT_ENDPOINT="https://leona.xiyanshan.com/v1/verdict";exportasyncfunctionqueryVerdict(boxId:string){constsecretKey=process.env.LEONA_SECRET_KEY!;constendpoint=process.env.LEONA_ENDPOINT||DEFAULT_ENDPOINT;constbody=JSON.stringify({boxId});consttimestamp=Date.now().toString();constnonce=crypto.randomBytes(16).toString("base64url");constbodySha256=crypto.createHash("sha256").update(body).digest("hex");constsigningText=`${timestamp}\n${nonce}\n${bodySha256}`;constsignature=crypto.createHmac("sha256",secretKey).update(signingText).digest("base64url");constresp=awaitfetch(endpoint,{method:"POST",headers:{"Authorization":`Bearer${secretKey}`,"Content-Type":"application/json","X-Leona-Timestamp":timestamp,"X-Leona-Nonce":nonce,"X-Leona-Signature":signature,},body,});consttext=awaitresp.text();if(!resp.ok)thrownewError(`verdict failed:${resp.status}${text}`);returnJSON.parse(text);}

注意:上面示例为了讲清楚直接写了Authorization: Bearer <secretKey>(公开契约如此)。生产系统里你至少要:

  • 禁止把 secretKey 写入任何日志;
  • 把异常文本做截断;
  • 记录 error_type(签名/时间窗/网络/5xx),而不是原文。

11) 幂等与并发:single-use 语义下最容易踩坑的“竞态条件”

一旦你把/v1/verdict接到生产流量里,马上会遇到并发问题:

  • 同一个请求被重试(客户端重发、网关重试、队列重投)
  • 同一个用户触发多个并行业务请求(多端、并发点击)
  • 业务链路里有多个模块都试图“查询一次”

在 single-use 语义下,最危险的情况是:两个并发请求同时去兑换同一个 BoxId,其中一个成功、另一个失败,然后你在业务里把失败当成“系统不稳定”。

解决方案是把幂等写进后端:

  • boxId作为唯一键落库
  • 用“先查后写 + 唯一约束”或“事务/锁”保证并发下只写入一次

11.1 Postgres 幂等落库(示意)

createtableleona_verdict_cache(box_idtextprimarykey,report_json jsonbnotnull,created_at timestamptznotnulldefaultnow());

写入时使用insert ... on conflict do nothing,然后再读回:

  • 如果写入成功:说明你是第一个兑换者
  • 如果冲突:说明另一个并发已经写入,你直接读取即可

这类“幂等 + 唯一键”是生产系统里处理 single-use token 的常规套路。


12) 错误分类(error taxonomy):不要把所有失败都当成“HTTP 500”

把错误分类做清楚,会直接提升你集成上线后的排障速度。

建议至少分这几类(你可以按业务需要扩展):

  • auth_failed:SecretKey 错误/权限错误
  • signature_mismatch:签名不匹配(实现错误、body 不一致、base64url/padding 差异)
  • timestamp_skew:时间窗错误(设备/环境时钟偏移、重放保护)
  • nonce_replay:nonce 重放
  • network_timeout:网络超时
  • upstream_5xx:上游 5xx
  • boxid_consumed:BoxId 已被消费(通常是并发/重试导致)

重要的是:你的业务决策系统需要知道“失败是否可重试”。

  • network_timeout可能可重试(但要避免重试导致二次消费)
  • signature_mismatch不可重试,必须修代码
  • timestamp_skew可能可恢复(校时/重建 session),但要可诊断

13) 回归测试:把“能跑”变成“可持续迭代”

如果你想把这条链路长期维护下去,至少需要三层测试:

13.1 签名单元测试(必须有)

用本文的固定测试向量锁死签名实现,避免某次重构把 JSON 序列化或 base64url 细节改坏。

13.2 合约测试(contract test)

把请求头、body 结构、必填字段做成测试:

  • 缺 header 应当失败
  • body JSON 多空格/字段名大小写不一致是否会导致签名不一致

13.3 业务回归(policy regression)

把历史 evidence report 落库之后,你就能做策略回放:

  • 同一批历史样本,在策略 v1/v2 下的 decision 分布变化
  • clean OEM 样本是否被误杀(这在 v0.2.0 公开计划里被当成门禁)

这一步很关键:它把“安全”从一次性集成变成持续工程。


14) 你最终应该交付什么(给团队的验收物清单)

如果你在团队里推动这个落地,我建议你把验收物写成“可以看、可以跑、可以回归”的东西:

  • 一个内部接口:/internal/leona/exchange(或等价)
  • 一个落库表:leona_verdict_cache(或等价)
  • 一套签名单测:固定向量 + base64url/sha256 校验
  • 一套指标与告警:成功率、P95、错误分类、落库成功率
  • 一份集成 runbook:怎么排查签名失败、时间窗错误、并发消费

做到这些,你的“BoxId → 证据报告 → 策略动作”链路才算真正进入生产形态。


15) 签名实现最容易踩的 10 个坑(几乎都发生在“细节不一致”)

下面这些坑,你只要踩过一次就会记一辈子。把它们写进团队的 code review checklist,会比事后排障省很多时间。

  1. timestamp 单位错:秒 vs 毫秒。公开契约里是unix-time-ms
  2. nonce 不够随机:不要用递增数或时间戳当 nonce;至少 16 bytes 随机。
  3. base64 与 base64url 混用:header 里要求 base64url;+//要替换为-/_
  4. padding 处理不一致:有的实现去掉=,有的保留。公开示例使用“不带 padding”。
  5. JSON 序列化不稳定:字段顺序、空格、换行不同都会导致 body hash 不同。
  6. bodySha256 计算对象错:必须对“最终发送的 body 字节”做 sha256,而不是对某个对象结构。
  7. 签名输入拼接错:必须是timestamp + "\n" + nonce + "\n" + sha256(body),换行符与顺序必须一致。
  8. 字符编码不一致:一定要 UTF-8。
  9. 把 secretKey 当成 token 打印到日志:这类事故一旦发生,唯一正确动作是立刻换钥并做安全事件复盘。
  10. 把错误信息原样回传给客户端:尤其在 5xx/签名错误时,不要把上游响应原文透传给前端。

把这些坑写成 checklist 后,工程质量会有肉眼可见的提升。


16) JSON 规范化:为什么 Python 示例要写separators=(",", ":")

你会注意到公开 Python 示例里有一句:

json.dumps({"boxId":box_id},separators=(",",":"))

这不是“代码洁癖”,而是为了保证 body 的字节序列稳定

签名里要对 requestBody 做 sha256。如果你的 JSON 序列化会插入多余空格:

  • {"boxId": "xxx"}
    vs
  • {"boxId":"xxx"}

它们语义相同,但字节不同,sha256 不同,签名自然不同。

因此,在任何语言里,你都应该把“最终发送的 body 字节序列”固定下来:

  • Node:JSON.stringify默认没有空格,一般稳定。
  • Python:显式指定 separators,避免空格。
  • Java/Go:确保输出的 JSON 与你计算 hash 的 JSON 完全一致。

最保险的方式仍然是:用固定测试向量做单测,把“body 的精确字符串”也锁死。


17) BoxId 在业务链路里怎么传:字段命名、追踪与审计

BoxId 的使用不应该是“临时加个字段”。你需要把它当成一种业务级证据关联键。

17.1 建议的字段策略

  • App → 后端:建议使用明确字段名,例如leonaBoxId(body 字段)或X-Leona-BoxId(header)。
  • 后端内部:统一叫boxId,并把它写入 request context(便于链路追踪)。

17.2 追踪(Tracing)建议

  • 为每次兑换建立requestId(业务已有就复用)。
  • 日志里记录:requestIduserIdboxIddecisionerror_typelatency_ms
  • 把“兑换发生在哪个业务动作”也记录下来(login/payment/posting)。

这样你的证据链才真正可审计:你能回答“这个用户为什么被挑战/拒绝”。


18) 重试策略:什么能重试、什么绝不能重试

single-use 语义让重试变得微妙:你既想提高可用性,又不能因为重试导致二次消费与混乱。

建议把重试分成两层:

18.1 后端调用/v1/verdict的重试(谨慎)

只对“明显未到达上游”的错误做一次短重试,例如:

  • 连接建立失败
  • DNS/网络瞬断

一旦你已经拿到明确的 HTTP 响应(尤其是非 2xx),不要盲目重试。

18.2 业务侧的重试(幂等 + 查缓存优先)

业务侧如果要重试同一个 boxId:

  • 必须先查缓存/落库结果
  • 查不到再考虑兑换

如果你把“查缓存优先”做对了,大部分重试都不会触发二次消费。


19) 证据落库的扩展字段:你未来一定会想要这些

前面给了最小落库字段,但真实系统上线后,你往往会想要更多字段来支持运营与回归:

  • decision:当时的动作(allow/challenge/deny)
  • policy_version:策略版本号(用于回放)
  • risk_tier:业务风险等级(高价值/低价值)
  • app_version/sdk_version:定位某次版本引入的误报
  • country/regionnetwork_type:解释性维度(注意合规)

这些字段不需要一口气全上,但你要给 schema 留扩展空间。


20) 把文章写“更像实战”的最后一招:给出验收问答

你把下面这组问答贴到 PR 描述或上线评审里,基本就能把讨论从“水文”拉到工程层面:

  • 问:BoxId 兑换失败时,我们能区分是签名问题还是网络问题吗?

  • 答:能。我们有固定签名单测 + error taxonomy + 指标分布。

  • 问:BoxId 被并发消费时会发生什么?

  • 答:后端以 boxId 为唯一键落库,先查缓存再兑换;并发下只会写入一份,其他请求走缓存。

  • 问:策略误杀如何回滚?

  • 答:策略版本化在后端,灰度发布,回滚不依赖发版;证据报告落库可回放回归。

  • 问:SecretKey 泄漏的应急预案是什么?

  • 答:立刻换钥 + 排查泄漏路径 + 回收日志/权限 + 补监控告警。

这四问四答能把“是否能用”说得非常清楚。


21) 性能与成本:为什么“先落库再决策”反而更省钱

很多团队担心“多一次后端调用会不会太慢、太贵”。实际工程里,只要你把缓存与落库做对,证据链往往是可控的:

  • /v1/verdict只在关键业务动作发生时调用(登录/支付/发帖/领券),不是每个请求都调。
  • single-use 语义要求你落库;落库后,同一业务链路的后续查询都走你自己的缓存/数据库,不再打上游。
  • 决策在后端做,意味着你可以把策略做成“轻量函数”,不需要端上复杂计算。

更重要的是:你用落库换来的,是“可审计、可回放、可回归”的工程能力,这会显著降低误报治理的人力成本。


22) 隐私与合规:证据链要可用,也要可控

做设备/环境证据链时,务必把“最小必要”原则写进规范:

  • 只持久化业务确实需要的字段;
  • 给证据报告设置访问权限与留存周期(例如 30/90/180 天);
  • 日志与指标避免记录敏感原文,优先记录聚合统计与错误类型;
  • 如果需要用于模型训练或风控分析,尽量做脱敏与分级授权。

这部分不属于 Leona 专属,而是任何“设备证据平台”都会面对的工程现实。


23) 最后的落地建议:把它当成“产品能力”交付给业务方

如果你只把它当成一段调用代码,半年后你会发现没有人维护、没有人敢改、出了事也没人能解释。
更好的方式是把它当成“产品能力”交付:

  • 有清晰的接口(内部 API)
  • 有明确的门禁与指标
  • 有可回放的证据落库
  • 有可灰度的策略版本

做到这四点,你的 BoxId 证据链才算真正进入“可持续”的状态。


24) 一句话总结

把 BoxId 当作“证据兑换券”,把/v1/verdict当作“后端证据报告接口”,再配上“幂等落库 + 错误分类 + 固定签名单测 + 分层策略”,你就拥有了一条能上线、能运维、能迭代的移动端证据链。

补充一句现实经验:先把签名实现与幂等落库做对,再谈策略与覆盖面;否则你会在“到底是系统不稳定还是我们实现错了”的争论里浪费大量时间。

当这条链路稳定后,你会发现移动端安全讨论会从“谁更会写检测”转向“证据是否成立、策略是否合理、误报如何治理”——这才是工程化的胜利。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 21:54:50

3PEAK思瑞浦 TPA2674-SO2R SOP14 运算放大器

特性 供电电压:4V至36V差分输入电压范围至电源轨&#xff0c;可作为比较器工作 输入轨至-Vs 快速响应: -带宽:10MHz -响应率:15 V/us 高PSRR:在100kHz时为80dB偏移电压:在25C时最大3mV 工作温度范围:-40C至125C

作者头像 李华
网站建设 2026/5/11 21:45:39

如何快速掌握Layerdivider智能图像分层:3步实现PSD自动化分解

如何快速掌握Layerdivider智能图像分层&#xff1a;3步实现PSD自动化分解 【免费下载链接】layerdivider A tool to divide a single illustration into a layered structure. 项目地址: https://gitcode.com/gh_mirrors/la/layerdivider 你是否曾面对复杂的插画作品&am…

作者头像 李华
网站建设 2026/5/11 21:44:57

哈尔滨工业大学 837 网安自命题开源资料+笔记+经验贴

作者26年哈理工数据科学专业网安小白跨考工大本部网安专硕&#xff0c;作为一个非本校的837跨考选手&#xff0c;我深知备考这样一个小众自命题的不易&#xff0c;我的备考历程完全是有赖于往届同学&#xff08;感谢zyx学长&#xff09;的帮助以及guoJohnny前辈的资料库才会如此…

作者头像 李华
网站建设 2026/5/11 21:44:54

Matlab repelem函数进阶玩法:从向量到多维数组,看这一篇就够了

Matlab repelem函数进阶玩法&#xff1a;从向量到多维数组的深度探索 在数据处理和科学计算领域&#xff0c;Matlab一直是工程师和研究人员的得力工具。而repelem函数作为数组操作中的瑞士军刀&#xff0c;其潜力远超过大多数用户日常使用的基础功能。本文将带您深入探索repele…

作者头像 李华