在javascript (不使用节点)上,当CBOR编码使用库(https://github.com/paroga/cbor-js)和使用CBOR online (https://cbor.me/)时,我面临不同的结果。注意,即使使用最近的CBOR库,结果也是相同的。
例如,设置一个对象,例如:
const initial = { 1: "John", "-2": 456 };使用CBOR online进行编码: a201644a6f686e622d321901c8。详情如下:
A2 # map(2)
01 # unsigned(1)
64 # text(4)
4A6F686E # "John"
62 # text(2)
2D32 # "-2"
19 01C8 # unsigned(456)现在,在javascript上使用CBOR库进行编码会产生不同的结果: a26131644a6f686e622d321901c8
在CBOR online上解码上面的十六进制时,我得到了:{"1":"John","-2":456}。结果几乎与常量‘初始值’相同,只是键1现在以引号(")出现。
CBOR联机将我的十六进制值重新格式化为一个更“可读”的视图:
A2 # map(2)
61 # text(1)
31 # "1"
64 # text(4)
4A6F686E # "John"
62 # text(2)
2D32 # "-2"
19 01C8 # unsigned(456)参见下面的Javascript代码:
//convert an array of bytes (as 8 bits) to string of Hex. ensure that Hex value are not return with 1 digit but 2 digits. ie '01' instead of '1'
function toHexString(byteArray) {
var s = '';
byteArray.forEach(function(byte) {
s += ('0' + (byte & 0xFF).toString(16)).slice(-2);
});
return s;
}
const initial = { 1: "John", "-2": 456 };
var encoded = CBOR.encode(initial);
var encodedHex = toHexString(Array.from(new Uint8Array(encoded)));
console.log ( encodedHex );我可以手动替换特定的十六进制值,例如:
“61 31 64”改为“01 64”
但不要想入非非地把它写成清单,这对于涵盖所有可能的选择都是很重要的。
有人有一个解决办法,因为我需要我的结果是'a201644a6f686e622d321901c8‘而不是'a26131644a6f686e622d321901c8’?
发布于 2021-12-17 16:12:39
Javascript中的对象键
在需要与基于JSON的应用程序交互的应用程序中,通过仅将键限制为文本字符串来简化转换。
实际上,cbor-js包使用Object.keys方法这里,它将所有键作为字符串返回。Javascript不区分数字和它们的字符串值,而是将{'1':1, 1:2}视为{'1':2} (而cbor.me则将其视为包含两个条目的映射)。
用改进的cbor-js解决方案
您的示例表明,您希望CBOR将非负数字键作为数字处理。这可以通过cbor-js源代码上的以下修补程序来实现:
diff --git a/cbor.js b/cbor.js
--- a/cbor.js
+++ b/cbor.js
@@ -164,7 +164,10 @@ function encode(value) {
writeTypeAndLength(5, length);
for (i = 0; i < length; ++i) {
var key = keys[i];
- encodeItem(key);
+ if (isNaN(key) || Number(key) < 0)
+ encodeItem(key);
+ else
+ encodeItem(Number(key));
encodeItem(value[key]);
}
}有了这个变化,Node.js给了我
> Buffer.from(cbor.encode({1:'John','-2':456})).toString('hex'))
'a201644a6f686e622d321901c8'或者,您甚至可以将负数键视为数字键,方法是在上面的修补程序中省略|| Number(key) < 0。这给了我们
> Buffer.from(cbor.encode({1:'John','-2':456})).toString('hex'))
'a201644a6f686e211901c8'
A2 # map(2)
01 # unsigned(1)
64 # text(4)
4A6F686E # "John"
21 # negative(1)
19 01C8 # unsigned(456)使用cbor的解决方案
与cbor-js不同,cbor包允许您对Javascript Map进行编码,后者将数字与字符串键区分开来:
> Buffer.from(cbor.encode(new Map().set(1,'John').set(-2,456))).toString('hex')
'a201644a6f686e211901c8'https://stackoverflow.com/questions/70316299
复制相似问题