繁体   English   中英

如何在 Python 和 JavaScript 中以相同的方式散列“json”嵌套字典?

[英]how to hash a “json” nested dictionary identically in Python and JavaScript?

在 JavaScript 和 Python 中一致散列仅限于 JSON 可以表示的对象/字典的最佳方法是什么? 在许多不同的语言中呢?

当然,在许多不同的语言中都有一致实现的散列函数,它们采用字符串,但要散列对象,您必须首先将其转换为字符串表示。

我想要一个哈希函数,它总是为任何语言的同一个字典返回相同的值,但 JSON 规范不保证序列化表示中键的顺序。

json.dumps()JSON.stringify()行为是否相同? 你将如何验证这一点?

如果没有,是否有包含多种语言库的序列化格式(我实际上对 Python 和 JavaScript 感兴趣,但也对所有语言感到好奇),不需要调用者进行任何额外处理即可产生一致的结果?

我会把这分成两个问题。

  1. 如何在 JavaScript 和 Python 中获得相同的序列化字符串?
  2. 您应该使用哪个字节数组散列函数? 它必须是在 JavaScript 和 Python 中具有相同实现的既定算法。

使用(1)获取两个字符串,然后使用UTF8编码,然后使用(2)获取哈希值。

由于(2)很简单,我将只解决(1)。

确保生成的两个 JSON 字符串相同的问题涉及多个方面。

  • 您需要使用未格式化的 JSON(没有多余的空格、制表符或换行符)。
  • 必须以相同的方式处理空值。 如果值为空,某些序列化程序默认会丢弃字典键值对。
  • 字典中键值对的顺序必须一致。
  • JSON 数字序列化应该是一致的。 例如,不能将整数 one 在一侧序列化为1在另一侧序列化为1.0 (不过,这可能不是什么大问题。)
  • 两者的字符串编码应该相同。 JSON 允许序列化为 Unicode 文本,只要求"\\在 JSON 字符串中被反斜杠转义。然而,大多数序列化程序做的比必要的多,并将几乎所有的 Unicode 字符减少到\\uXXXX等价物。有关详细信息,请参阅json.org JSON 字符串编码。消除所有歧义的一种方法是仅在绝对必要时才转义。

您需要确保所有这些都在 JavaScript 和 Python 之间匹配。 我使用过的大多数 JSON 序列化库都为我在上面列表中提到的所有内容提供了配置挂钩。 不幸的是,我对 JavaScript 或 Python 库不是很熟悉。

JSON 是一种定义良好的语言,用于表示对象的状态。 这些函数的行为不同,但它们的行为相同

例如:

json.dumps({'hello':'goodbye', 123: 456})

可能产生:

{"hello":"goodbye", "123": 456}

{"123": 456, "hello":"goodbye"}

如果您传入indent参数,那么您将获得更多不同结果的可能性。

大多数语言如果还没有处理 JSON 的内置方法(例如 Python 和 JS),那么它们将拥有一个完全足够的 3rd 方实用程序(请参阅 Newtonsoft JSON library for .NET)

我知道的每种语言都会产生有效的 JSON,这意味着它可以被提供 JSON 解析器的其他语言解析。

我想我可以尝试一个实际的例子。

在javascript中我做了:

import stringify from 'json-stable-stringify'
import sha256 from 'simple-sha256'

hash_str = sha256(stringify({'hello':'goodbye', '123': 456}))
// hash_str = 72804f4e0847a477ee69eae4fbf404b03a6c220bacf8d5df34c964985acd473f

json-stable-stringify保证排序的 json。 sha256允许 nodejs/浏览器兼容性。

在 python 3.8 中,我做了:

import hashlib
import json

hash_str = hashlib.sha256(json.dumps({'hello':'goodbye', '123': 456}, sort_keys=True, separators=(',', ':')).encode("utf-8")).hexdigest()
# hash_str = 72804f4e0847a477ee69eae4fbf404b03a6c220bacf8d5df34c964985acd473f

我还没有进行广泛的测试,但是使用我尝试过的 json 对象,它已成功匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM