首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >密钥格式的CBOR编码问题

密钥格式的CBOR编码问题
EN

Stack Overflow用户
提问于 2021-12-11 15:09:00
回答 1查看 510关注 0票数 0

在javascript (不使用节点)上,当CBOR编码使用库(https://github.com/paroga/cbor-js)和使用CBOR online (https://cbor.me/)时,我面临不同的结果。注意,即使使用最近的CBOR库,结果也是相同的。

例如,设置一个对象,例如:

代码语言:javascript
复制
const initial = { 1: "John", "-2": 456 };

使用CBOR online进行编码: a201644a6f686e622d321901c8。详情如下:

代码语言:javascript
复制
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联机将我的十六进制值重新格式化为一个更“可读”的视图:

代码语言:javascript
复制
A2             # map(2)
   61          # text(1)
      31       # "1"
   64          # text(4)
      4A6F686E # "John"
   62          # text(2)
      2D32     # "-2"
   19 01C8     # unsigned(456)

参见下面的Javascript代码:

代码语言: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’?

EN

回答 1

Stack Overflow用户

发布于 2021-12-17 16:12:39

Javascript中的对象键

CBOR规范,第5.6节说:

在需要与基于JSON的应用程序交互的应用程序中,通过仅将键限制为文本字符串来简化转换。

实际上,cbor-js包使用Object.keys方法这里,它将所有键作为字符串返回。Javascript不区分数字和它们的字符串值,而是将{'1':1, 1:2}视为{'1':2} (而cbor.me则将其视为包含两个条目的映射)。

用改进的cbor-js解决方案

您的示例表明,您希望CBOR将非负数字键作为数字处理。这可以通过cbor-js源代码上的以下修补程序来实现:

代码语言:javascript
复制
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给了我

代码语言:javascript
复制
> Buffer.from(cbor.encode({1:'John','-2':456})).toString('hex'))
'a201644a6f686e622d321901c8'

或者,您甚至可以将负数键视为数字键,方法是在上面的修补程序中省略|| Number(key) < 0。这给了我们

代码语言:javascript
复制
> 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进行编码,后者将数字与字符串键区分开来:

代码语言:javascript
复制
> Buffer.from(cbor.encode(new Map().set(1,'John').set(-2,456))).toString('hex')
'a201644a6f686e211901c8'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70316299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档