gpt4 book ai didi

javascript - 如何从 JavaScript 对象生成校验和?

转载 作者:数据小太阳 更新时间:2023-10-29 04:34:53 24 4
gpt4 key购买 nike

我需要从 JavaScript 对象生成校验和。
不幸的是,由于 JavaScript 的对象排序,似乎没有一种简单的方法来完成此操作。例如,拿这些对象:

var obj1 = {type:"cake",quantity:0}
, obj2 = {quantity:0,type:"cake"};

我认为这些对象的数据相等,并且希望它们的校验和相同。我真的不关心对象的顺序,只要它们中的数据相同即可。
唉,两者的JSON.stringify其实是不相等的;由于生成对象校验和的唯一方法是通过其字符串表示,而 JSON.stringify 编辑的表示不相等,因此我的校验和将不相等!
我提出的一种解决方案是根据预定义的模式重新创建对象,如下所示:

var schema = ["type","quantity"];
function sortify(obj,schema){
var n={};
for(i in schema)
n[schema[i]]=obj[schema[i]];
return n
}

运行 JSON.stringify(sortify(obj1,schema))==JSON.stringify(sortify(obj2,schema)) 将返回 true... 但在创建新对象和数据混洗的代价。

我的另一个解决方案是将 JSON.stringify 方法替换为从预定义模式中挑选键并将其值字符串化,然后将它们连接在一起的方法。函数内容如下:

function smarterStringify(obj,schema){
var s="";
for(i in schema)
s+=JSON.stringify(obj[schema[i]]);
return s
}

忽略这个方法没有返回正确的 JSON 的事实(它足够接近我正在尝试做的事情的例子),它在速度上比第一个有很大的改进(至少在我的 Chrome 操作系统中)浏览器,你可以在这里自己检查:http://jsperf.com/sort-then-json-stringify-vs-smarter-stringify),当然它使两个对象字符串表示相等!

但是,我只是想知道我是否遗漏了一些东西,并且一直有一个内置方法可以解决类似的问题,它不会 a) 将 JavaScript GC 推向病态情况或 b) 做太多的字符串串联。我宁愿不做那些。

最佳答案

3 年后......

我遇到这个问题是因为我想散列我的 JSON 对象以为我的 HTTP 响应创建 Etag。所以我最终为 Node 编写了自己的解决方案,jsum ,归结为一个简单的序列化程序:

/**
* Stringifies a JSON object (not any randon JS object).
*
* It should be noted that JS objects can have members of
* specific type (e.g. function), that are not supported
* by JSON.
*
* @param {Object} obj JSON object
* @returns {String} stringified JSON object.
*/
function serialize (obj) {
if (Array.isArray(obj)) {
return JSON.stringify(obj.map(i => serialize(i)))
} else if (typeof obj === 'object' && obj !== null) {
return Object.keys(obj)
.sort()
.map(k => `${k}:${serialize(obj[k])}`)
.join('|')
}

return obj
}

然后您可以获取结果并使用常用算法(例如 SHA256)对其进行哈希处理,或者使用 jsum 包中的 digest 的便捷方法.


请注意许可证 here !

关于javascript - 如何从 JavaScript 对象生成校验和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24917152/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com