我有一个如下所示的JavaScript对象:
Const data = {
x: 1,
y: 2,
z: 3
a: 4,
b: 5,
c: 6
};
我们在Angular 6应用程序中提供了一个签名服务,该服务对这个对象进行字符串化处理,对字符串进行哈希处理,然后为其添加签名。然后将其保存到Firestore数据库。数据库喜欢按字母顺序对属性进行排序,因此最终看起来像这样:
{
a: 4,
b: 5,
c: 6,
x: 1,
y: 2,
z: 3
}
当我们从数据库中检索此对象并尝试验证签名时,它会失败。之所以失败,是因为当您对 this 对象进行字符串化处理时,与我们对其进行签名时相比,属性的字母顺序会导致生成不同的字符串。这将导致产生与原始签名不匹配的其他哈希值。
我们当前解决此问题的方法是,我们在代码中按字母顺序写出属性的顺序,但是我们想做一个简单的证明(例如,如果另一个开发人员出现并在底部添加了一个属性,说d,但没有意识到它应该按字母顺序排列)。一位同事告诉我,有一种方法可以告诉Javascript根据其自己的算法对属性进行排序。如果可以做到,则在进行字符串化,散列和签名之前,应根据该算法对属性进行排序,然后从数据库中检索对象时,请执行相同的操作:根据Javascript的算法对属性进行排序,对字符串进行字符串化处理,哈希和验证。
有人知道这个Javascript顺序是什么以及如何执行吗?
答案 0 :(得分:1)
创建一个自定义的stringify函数,该函数可按正确的顺序处理对象。
const data = {
a: 4,
b: 5,
c: 6,
x: 1,
y: 2,
z: 3
}
function customStringify(d){
return '{'+Object
.entries(d)
.sort(([,v1],[,v2])=>v1-v2)
.map(([k,v])=>`${k}:${v}`)
.join(",")+'}';
}
const res = customStringify(data);
console.log(res);
答案 1 :(得分:1)
JS无法自然地订购对象,您必须自己动手修改它。
我想到的最简单的方法是使用数组并从那里排序。
这将返回以下数组...
Object.entries(test).sort((a, b) => a[1] - b[1])
返回
[ [ 'x', 1 ],
[ 'y', 2 ],
[ 'z', 3 ],
[ 'a', 4 ],
[ 'b', 5 ],
[ 'c', 6 ] ]
如果要将其放回对象中,
Object.assign({}, ...Object.entries(test).sort((a, b) => a[1] - b[1]).map(([key, value]) => ({[key]: value})) )
返回
{ x: 1, y: 2, z: 3, a: 4, b: 5, c: 6 }