设为首页 收藏本站
开启辅助访问 快捷导航
菜单
猿人部落 主页 资讯 查看内容

物联网专用数据交换格式CBOR

2019-8-1 05:12 发布者: 古田高山 评论 0 查看 2795
前言 本文将先容物联网范畴的JSON格式——CBOR,CBOR是专门为受限定物联网终端筹划的数据互换格式,该格式轻量轻便,

前言

本文将先容物联网范畴的JSON格式——CBOR,CBOR是专门为受限定物联网终端筹划的数据互换格式,该格式轻量轻便,可以简朴明白为二进制情势JSON格式。CBOR格式可以与COAP协议组合利用,如同HTTP+JSON;别的,CBOR也是COSE的根本。

CBOR简述

CBOR可分为8个主范例(Major Type),CBOR格式为了界说8种差别的范例,采取首字节的高3位界说主范例。 首字节的低5位在差别的主范例表现长度(除主范例0和主范例1),如果长度指示不敷,则依次利用后续字节。

主范例 名称 首字节 简朴阐明
主范例0 无符号整数 0x00或 0x10 根本范例
主范例1 负整数 0x20或 0x30 根本范例
主范例2 字节数组 0x40或 0x50 根本范例
主范例3 字符串 0x60或 0x70 根本范例
主范例4 数组 0x80或 0x90 组合范例,可嵌套恣意范例
主范例5 键值对 0xA0或 0xB0 组合范例,可嵌套恣意范例
主范例6 扩展 0xC0或 0xD0 扩展范例
主范例7 数组 0xE0或 0xF0 浮点数与简朴范例

无符号整数 an unsigned integer

主范例0,无符号整数编码后首字节为0b000_XXXXX。为了表达差别长度的无符号整数,CBOR格式利用第一个字节的低5位表现整数范例

  • 0b000_11000 uint8_t
  • 0b000_11001 uint16_t
  • 0b000_11010 uint32_t
  • 0b000_11011 uint64_t
    请注意,无符号整数0到23直接表达,无需利用整数范例。
    比方:
  • 10 编码后 0x0A
  • 24 编码后 0x1818
  • 100 编码后 0x1864
  • 1000 编码后 0x1903E8

负整数 a negative integer

主范例1,无符号整数编码后首字节为0b001_XXXXX。负整数的编码方式与无符号整数相似。
比方:

  • -10 编码后 0x29
  • -24 编码后 0x37
  • -100 编码后 0x3863
  • -1000 编码后 0x3903E7

字节数组 a byte string

主范例2,字节数组编码后首字节为0b010_XXXXX。为了表达字节数组长度,如果字符数组的长度小于即是23,那么直接利用首字节的低5位表现;如果长度大于或即是24字节,那么利用第二个字节表现长度;如果长度大于即是256字节,那么利用第二和第三个字节表现长度。
CBOR长度形貌
CBOR格式中一样寻常采取多字节组合的方式表达长度。CBOR如许的长度形貌方法便于嵌入式装备利用C语言分析CBOR格式,节流名贵的栈空间与堆空间。
比方:

  • HEX格式01020304 编码后 0x4401020304
  • 长度为23的字节数组 编码后 0x57XX…
  • 长度为24的字节数组 编码后 0x5818XX…
  • 长度为100的字节数组 编码后 0x5901F4XX…
    本质来说,CBOR仅为这些原始的字节数组增长了一个长度形貌。

特别注意点

别的在CBOR格式编码钱的字节数组一样寻常采取采取小写h开头,在单引号中形貌HEX格式内容,比方

  • h’01020304’

字符串 a text string

主范例3。字符串范例编码后首字节为0b011_XXXXX。字符串格式与字节数组格式非常相似,只是字节数组格式人类不可读,而字符格式人类可读。字符串格式表达长度的方式与字节数组范例相似。
比方:

  • “a” 编码后 0x6161
  • “IETF” 编码后 0x6449455446
  • 长度为24的字符串 编码后 0x781830XX…

数组 an array of data items

主范例4。 数组编码后首字节为0b100_XXXXX。以上四种均为根本格式,而数组为一种符合,还可以与自身或其他范例嵌套。数组中数组元素个数(不是编码后字节长度)的表达方式与字节数组范例相似。
比方:

  • [1,2,3] 编码后 0x83010203
  • [1,[2,3], [4,5]] 编码后 0x8301820203820405,此处包罗3个数组,第一个数组0x83,表现元素个数为3,第二个0x82b表现元素个数为2,第3个编码后元素个数为3。
    对于数组部门,RFC7049也有些表述不清的地方。在主范例无符号整数中,若整数值凌驾24(0x18),该值将会被CBOR编码为0x1818。
  • [24, 25, 26] 编码后为 0x8318181819181A,不是0x83181818。
  • [500, 501, 502] 编码后为0x831901F41901F51901F6,不是0x8301F401F501F6

特别注意点

在JSON范例中,键名Key必须为字符串,但是在CBOR格式中,键名Key可以是整数。CBOR通过这种方式可以节流物联网终端开销。

键值对 a map of pairs of data items

主范例5。键值对编码后首字节为0b101_XXXXX。键值对也是一种符合范例,可以嵌套恣意范例。键值对范例中键值对个数(不是编码后的字节长度)的表达方式与字节范例表达方式相似。比方

  • {“a”:1, “b”:[2,3]} 编码后 0xA26161016162820203, 此中0x616101中 0x616101表现一个键值对,0x6161表现字符串编码"a", 0x01表现值1。此中0x6162820203表现另一个键值对,0x6162表现字符串编码"b",0x820203表现一个数组。
  • {1:2, 3:4} 编码后 0xA201020304 (还须要分析,JSON中键名不能为数字,而CBOR可以)

扩展范例

主范例6。扩展范例编码后首字节为0b110_XXXXX。CBOR通过增长Tag的方式扩展范例,满意未来的扩展。COSE规范中通过CBOR Tag界说了多种新范例。本文暂不详细睁开扩展范例,仅给出几个CBOR示例

  • 23(h’01020304’) 编码后 0xd74401020304

特别阐明

在CBOR扩展类范例形貌中,一样寻常以Tag编号开头,然后在小括号中()生存内容,内容可以是恣意一种CBOR范例。

浮点数与简朴范例

主范例7。浮点数与简朴范例编码后首字节为0b111_XXXXX。该范例界说了简朴范例,时间范例(Date和Time)、大整数(Bignum),10进制整数(Decimal)等。在主范例7中,首字节的高3位固定为0b111,首字节中低5位用于表现子范例。

简朴范例

首字节的低5位中0到23表现简朴类,界说如下:

  • 20 表达False
  • 21 表达True
  • 22 表达Null
  • 23 表达Undefined Value
    以是
  • False 编码后 0xF4
  • True 编码后 0xF5
  • Null 编码后 0xF6

时间范例

CBOR体验

参考依赖



    com.upokecenter
    cbor
    4.0.0-alpha2

还依赖了两个参考库joda-timehexdump


    org.lasinger.tools
    hexdump
    0.2.0


    joda-time
    joda-time
    2.10.2

整数相干

@Test
public void testInt() {
    CBORObject obj = CBORObject.FromObject(1);
    // 通过控制台打印
    byte[] bytes = obj.EncodeToBytes();
    String hexString = Hexdump.hexdump(bytes);
    System.out.println(hexString);
}

@Test
public void testInt100() {
    CBORObject obj = CBORObject.FromObject(100);
    // 通过控制台打印,打印方法省略
}

@Test
public void testIntNegative100() {
    CBORObject obj = CBORObject.FromObject(-100);
    // 通过控制台打印,打印方法省略
}

字节数组与字符串

@Test
public void testByteArray() {
    int length = 500;
    byte[] testByte = new byte[length];
    for (int i = 0; i < length; i++) {
        testByte[i] = 0x30;
    }
    CBORObject obj = CBORObject.FromObject(testByte);
    // 通过控制台打印,打印方法省略
}

@Test
public void testString() {
    CBORObject obj = CBORObject.FromObject("IETF");
    // 通过控制台打印,打印方法省略
}

@Test
public void testLargeString() {
    int length = 24;
    StringBuilder builder = new StringBuilder();

    for (int i = 0; i < length; i++) {
        builder.append("0");
    }

    CBORObject obj = CBORObject.FromObject(builder.toString());
    // 通过控制台打印,打印方法省略
}

数组

@Test
public void testArray() {
    CBORObject obj = CBORObject.NewArray();

    obj.Add(CBORObject.FromObject(1));
    obj.Add(CBORObject.FromObject(2));
    obj.Add(CBORObject.FromObject(3));
    // 通过控制台打印,打印方法省略
}

@Test
public void testArray24() {
    CBORObject obj = CBORObject.NewArray();

    obj.Add(CBORObject.FromObject(500));
    obj.Add(CBORObject.FromObject(501));
    obj.Add(CBORObject.FromObject(502));
    // 通过控制台打印,打印方法省略
}

/**
 * 嵌套数组 [1, [2,3], [4,5]]
 */
@Test
public void testMultiArray() {
    CBORObject obj = CBORObject.NewArray();
    obj.Add(CBORObject.FromObject(1));

    CBORObject subArray1 = CBORObject.NewArray();
    subArray1.Add(CBORObject.FromObject(2));
    subArray1.Add(CBORObject.FromObject(3));
    obj.Add(subArray1);

    CBORObject subArray2 = CBORObject.NewArray();
    subArray2.Add(CBORObject.FromObject(4));
    subArray2.Add(CBORObject.FromObject(5));
    obj.Add(subArray2);
    // 通过控制台打印,打印方法省略
}

@Test
public void testLargeArray() {
    CBORObject obj = CBORObject.NewArray();

    int length = 25;
    for (int i = 0; i < length; i++) {
        int temp = i + 100;
        obj.Add(CBORObject.FromObject(temp));
    }
    // 通过控制台打印,打印方法省略
}

键值对

@Test
public void testMap() {
    CBORObject obj = CBORObject.NewMap();

    obj.set(1, CBORObject.FromObject(2));
    obj.set(3, CBORObject.FromObject(4));

    // 通过控制台打印,打印方法省略
}

@Test
public void testJavaMap() {
    Map map = new HashMap<>();
    map.put("a", 1);
    map.put("b", 2);

    CBORObject obj = CBORObject.FromObject(map);
    // 通过控制台打印,打印方法省略
}

浮点型和简朴范例

@Test
public void testTrue() {
    CBORObject obj = CBORObject.FromObject(true);

    byte[] bytes = obj.EncodeToBytes();
    String hexString = Hexdump.hexdump(bytes);
    System.out.println(hexString);
}

@Test
public void testBigDecimal() {
    String decimalString = BigDecimal.valueOf(273.15).toString();
    CBORObject obj = CBORObject.FromObject(EDecimal.FromString(decimalString));
    // 通过控制台打印,打印方法省略
}

@Test
public void testDateTime() {
    DateTime dt = new DateTime(2013, 3, 21, 20, 04, 0);
    CBORObject obj = CBORObject.FromObject(dt.toDate());
    // 通过控制台打印,打印方法省略
}

扩展范例

@Test
public void testCBORTag() {
    byte[] array = new byte[] {0x01, 0x02, 0x03, 0x04};
    CBORObject obj = CBORObject.FromObjectAndTag(array, 23);
    System.out.println(obj.toString());

    byte[] bytes = obj.EncodeToBytes();
    String hexString = Hexdump.hexdump(bytes);
    System.out.println(hexString);
}

总结

  • CBOR格式是一种带有显着长度指示的传输协议,而常用的JSON格式并没有长度指示。长度指示可以资助终端装备在举行CBOR分析时节流名贵的堆空间。
  • CBOR格式支持键值对情势 Key-Value,Key可以是整数,而JSON格式中Key值只能是字符串。
  • CBOR格式中Date、Time、Decimal范例办理了物联网终端装备中时间日期与十进制数表达的标题。

参考资料

  • 【RFC7049 Concise Binary Object Representation (CBOR)】
  • 【示例代码】


路过

雷人

握手

鲜花

鸡蛋
收藏 邀请
上一篇:聚师网资讯看不到的眼睛下一篇:19年关于跨境电商,它的一些资讯干货,你们了解吗?

相关阅读

一周热门

头条攻略!

日排行榜

相关分类