【问题标题】:Serialization of numerical values in JSONJSON中数值的序列化
【发布时间】:2021-11-11 18:57:20
【问题描述】:

我注意到https://jwt.io/ 为包含以不同符号编写的数值的有效负载输出相同的 Base64 字符串。 例如,这两个有效载荷会产生相同的 Base64 字符串:

{
  "value": 0.000001
}
{
  "value": 1.0e-6
}

两者都产生:eyJ2YWx1ZSI6MC4wMDAwMDF9 解码后显示为:{"value":0.000001}

我在哪里可以找到有关此的更多信息?我想有一个以 RFC 或类似形式的规范。也感谢有关相关主题的非正式资源!

【问题讨论】:

    标签: javascript json floating-point jwt


    【解决方案1】:

    如何创建号码并不重要。我的意思是数字文字使用了哪种表示法。内部表示是 IEEE 754。当序列化发生时,两个值是相同的。所以预期相同的序列化输出。

    在数字被序列化为字符串的方式中,您可以读取Spec。 TLDR 取决于有效位数

    console.log(1e-6 === .000001)
    
    console.log(JSON.stringify(1e-6), 1e-6.toString())
    console.log(JSON.stringify(1e-7), 1e-7.toString())

    【讨论】:

    • 这个输出是由运行时环境决定的吗?由于我在浏览器中使用 JWT.io,这意味着此输出取决于 ecma 规范。当我尝试从其他地方使用它时会发生什么?也许其他一些平台以不同的方式呈现数字。所以 JSON 是不同的。并且 JWT 令牌的内容不同 - 数字签名失败......我想你看到了我想要找出的内容。
    • "这个输出是由运行环境决定的吗?" - 可能。 “当我尝试从其他地方使用它时会发生什么?”好吧,没什么。您有一个令牌,它是一个包含有效负载和签名的字符串。签名与有效负载匹配,而不是您解释有效负载的方式。
    • 感谢您的快速回答。可能我想的不是很清楚。这是我的思路:发行者必须使用有效载荷字节的 base64UrlEncode 创建散列。这意味着 JSON 对象的字节,即 JSON 文本的字节。此文本由发行者的运行时环境生成。然后我的代码以一些 JSON 对象的形式接收令牌,由一些 JSON 库解析。所以我没有服务器发送给我的逐字 JSON 字节。我还需要创建哈希。我的库将为我生成 JSON 文本。所以这个文本是由我的运行时 env/lib 决定的。
    • 我真的不明白你的情况。您似乎对所谓的“JSON 对象”有所了解。哪有这回事。 JSON 是一个字符串(句点)。因此,您的发行人签署了一个字符串。当您收到一个自包含的令牌时,您检查一个字符串的签名,确保它是有效的,然后将字符串反序列化为您的主机环境对象、结构、字节数组等等......目前尚不清楚您需要哪个额外的“哈希”假设您通常无法访问颁发者密码,以及为什么它必须使用相同的序列化。
    • 再次感谢您的耐心等待。关于这种情况,我同意你的看法。我知道 JSON 是一个字符串,并且签名是从该字符串的哈希派生的。 (这就是我所说的哈希)。考虑这种情况:服务器 A 向客户端 B 发送带有 0.0000001 的 JSON。客户端 B 上的端点使用这个原始字符串并从中创建一个 java JsonObject。现在,这个 JsonObject 被传递给其他一些组件。原来的字符串现在已经被垃圾回收了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多