• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Chihiro316
V2EX  ›  程序员

我用 deepseek 逆向了小米运动的卡路里算法,绷不住了

  •  
  •   Chihiro316 · 2h 34m ago · 651 views

    起因是主播最近在减肥,每天运动量不变,卡路里却忽高忽低,觉得其中必有蹊跷。让 deepseek 帮忙逆向看了一眼,看完是真绷不住。

    先说明前提:我没戴小米手环,手机放裤兜或边走边刷。手环走的是另一套算法,由手环自己算完传给手机,跟下面这些无关。

    我本以为这算法至少符合运动生理学。结果核心就三条:

    按分钟分档,只看步频

    每分钟步数 ≤138 → 0.04 卡/步 139–277 → 0.06 卡/步 ≥278 → 0.10 卡/步

    注意最后那档:278 步/分相当于 4.6 步/秒,那是苏炳添、陈妤颉这种选手的顶速。而且它要的是整整一分钟都这个频率——人类压根做不到。所以实际只有前两档在用。

    距离 = 步数 × 0.6 ,而且每次更新都取整

    不是最后乘一次,是每次同步来 n 步,就算 int(n × 0.6) 再累加。n=13 时 7.8 → 7 ,丢 0.8 米。同步越勤,丢得越多,所以你看到的是 0.59 而不是 0.6 。

    卡路里会重复累加(这是 bug )

    同一分钟内,它每次更新不是把最新值同步过去,而是把这分钟的旧值再往上加一遍。

    我做了个对照:

    19:20 正常走 54 步,没碰手机 → 2.16 卡 ( 54×0.04 ,正确) 19:21 走 40 步,边走边下拉刷新 → 8.28 卡 8.28 ÷ 40 = 0.207 卡/步,比它自己最高档的 0.10 还高一倍。

    日志里这一分钟被写了 8 次:

    2 步/0.08 → 14 步/0.64 → 17 步/1.32 → 28 步/2.44 → 33 步/3.76 → 35 步/5.16 → 38 步/6.68 → 40 步/8.28 每一个都是「上一次的值 + 这一次的累计值」。这就是为什么你越刷它越大。

    复现

    adb logcat -G 128M && adb logcat -c 走 5 分钟 adb logcat -d -v brief > walk.log 搜 srcDataMap = {calories=[...] 看同一个 time= 的 calories 是不是在涨 注意:logcat 分段时每行会重复带 I/fitness_xxx(pid): 前缀,直接删换行会漏读,得先剥前缀。

    写这些不是想证明小米多烂。就是觉得,每次当我觉得世界总不可能这么草台班子吧?现实就冲过来狠狠地给我上一课。

    一个天天摆在首屏、几千万人在看的数字,能偏 30%~100%,而且偏差取决于你刷不刷手机,挺神奇的。

    3 replies  •  2026-10-21 20:06:36 +08:00
    Ipsum
        1
    Ipsum  
       2h 33m ago via Android
    你这算啥?手表异常耗电才恶心
    x86
        2
    x86  
       2h 33m ago via iPhone
    最开始睡眠检测也是纯忽悠,后面改了不知道现在如何了
    shoaly
        3
    shoaly  
       2h 31m ago
    我一直以为是跟心率联动的, 心率是一个最大的指标. 结果实在算步数啊
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3203 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:37 · PVG 22:37 · LAX 07:37 · JFK 10:37
    ♥ Do have faith in what you're doing.