You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js与Flutter使用crypto包生成SHA256结果不一致问题咨询

问题根因
  • 核心差异来自不同平台下JSON序列化对浮点数的处理规则不一致:
    • Flutter Web编译为JavaScript目标,json.encode 本质调用JS的JSON.stringify,对于值为整数的浮点数(如3700.0)会自动序列化为无小数点的整数形式3700,和Node.js端默认JSON.stringify逻辑完全一致,所以哈希结果相同。
    • Flutter Android端运行在Dart VM中,默认json.encode会保留浮点数的小数点标识,将3700.0序列化为3700.0,导致最终拼接的待哈希字符串和Node.js端存在差异,哈希结果自然不同。
  • 次要排查点:需确认两边JSON序列化的键顺序、多余空格/换行、尾逗号规则完全一致,默认情况下两边无多余格式化空格,不会导致差异。
解决方案
  1. 统一数值类型:避免使用无必要的浮点数类型,将明确为整数的字段统一改为整数类型。示例中把invoiceAmount的值从3700.0改为3700,即可消除浮点数序列化差异。
  2. 对齐序列化规则:如果必须使用浮点数,自定义两边的序列化逻辑,对浮点数值统一格式输出,例如保留固定小数位、或转成字符串后再序列化。
  3. 前置校验:执行哈希前先打印两边拼接后的完整待哈希字符串,直接对比内容是否完全一致,可快速定位差异点。

修正后Dart代码

import 'dart:convert';
import 'package:crypto/crypto.dart';

void main() {
  final mapData = {
    "invoiceAmount": 3700, // 改为整数类型
    "notes": {
        "env": "np",
    }
  };
  final serializedStr = "abc-234-abc" + json.encode(mapData);
  // 可打印serializedStr和Node端结果做对比
  final bytes = utf8.encode(serializedStr);
  final digest = sha256.convert(bytes);
  print(digest);
}

修正后Node.js代码

const crypto = require('crypto')

const mapData = {
    "invoiceAmount": 3700, // 对应改为整数类型
    "notes": {
        "env": "np",
    }
}
const serializedStr = "abc-234-abc" + JSON.stringify(mapData)
const hash = crypto.createHash('sha256').update(serializedStr).digest('hex')
console.log(hash)

内容的提问来源于stack exchange,提问作者Shivang Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 18:24:04