目录

【基本结构】

【示例】

【特点】

【应用场景】

【示例代码】

【类似格式】


        TLV(Type-Length-Value) 是一种常用的数据编码格式,广泛应用于通信协议、数据存储和传输中。由于其灵活、高效、轻量等优点,在嵌入式物联网领域使用尤为广泛。

【基本结构】

  • Type(类型)/ 有些地方也成为Tag(标签)
    • 表示数据的类型或标识。
    • 通常是一个固定长度的字段(如1字节或2字节)。
    • 用于指示后续 Value 的含义或格式。
  • Length(长度)
    • 表示 Value 字段的长度。
    • 通常是一个固定长度的字段(如1字节或2字节)。
    • 用于确定 Value 的边界。
  • Value(值)
    • 实际的数据内容。
    • 长度由 Length 字段指定。

【示例】

        下面让我们用一个更直观的例子来说明 TLV 编码,比如 学生信息传输

  • 学号(ID): 1001
  • 姓名(Name): "张三"
  • 年龄(Age): 20

TLV 编码后的数据(16进制表示):

字段 Type(1字节) Length
(1字节)
Value(变长) 实际编码(Hex)
学号 0x01 (ID) 0x04 (4字节) 0x000003E9 (1001) 01 04 00 00 03 E9
姓名 0x02 (Name) 0x06 (6字节) "张\x00三\x00" (UTF-16编码) 02 06 5F 20 00 4E 09 00
年龄 0x03 (Age) 0x01 (1字节) 0x14 (20) 03 01 14

最终传输的 TLV 数据流(按顺序拼接): 01 04 00 00 03 E9 02 06 5F 20 4E 09 03 01 14

TLV 解析过程:

接收方按照 Type → Length → Value 的顺序解析:

  1. 读取 0x01(Type=学号)
    • Length=0x04 → 读取 4 字节 Value:00 00 03 E9 → 解析为 1001
  2. 读取 0x02(Type=姓名)
    • Length=0x06 → 读取 6 字节 Value:5F 20 00 4E 09 00 → 解析为 "张三"
  3. 读取 0x03(Type=年龄)
    • Length=0x01 → 读取 1 字节 Value:0x14 → 解析为 20

假设有一个 TLV 数据:A0 04 12345678

  • TypeA0(表示某种数据类型)。
  • Length04(表示 Value 的长度为4字节)。
  • Value12345678(实际数据)。

        注意:有时Length不在数据中体现,只要解码者事先知道每种Type对应的Length即可

【特点】

  • 灵活性: 通过 Type 字段可以扩展支持多种数据类型,而不影响现有的数据解析。
  • 自描述性: 每个 TLV 单元包含了处理所需的全部信息,不需要外部的上下文或元数据。
  • 高效性: 通过 Length 字段可以快速定位数据边界,减少解析开销。

【应用场景】

  • 通信协议: 如蓝牙、NFC、Modbus 等协议中常用 TLV 格式传输数据。
  • 数据存储: 如配置文件、数据库记录中常用 TLV 格式存储结构化数据。
  • 编码格式: 如 ASN.1、BER、DER 等编码格式基于 TLV 结构。

【示例代码】

#include <stdio.h>
#include <string.h>

void parseTLV(const char* data, int data_len) {
    int index = 0;
    while (index < data_len) {
        // 提取 Type
        char type[3] = {data[index], data[index + 1], '\0'};
        index += 2;

        // 提取 Length
        char length[3] = {data[index], data[index + 1], '\0'};
        index += 2;
        int value_len = strtol(length, NULL, 16); // 将 Length 转换为整数

        // 提取 Value
        char value[value_len + 1];
        strncpy(value, &data[index], value_len);
        value[value_len] = '\0';
        index += value_len;

        // 打印结果
        printf("Type: %s, Length: %d, Value: %s\n", type, value_len, value);
    }
}

int main() {
    // 测试数据
    const char* tlv_data = "A00412345678B002A1C103ABC";
    parseTLV(tlv_data, strlen(tlv_data));

    return 0;
}

输出结果:

Type: A0, Length: 4, Value: 12345678

Type: B0, Length: 2, Value: A1

Type: C1, Length: 3, Value: ABC

【类似格式】

        除了TLV,类似的通信格式还有BLE蓝牙广播协议所使用的LTD(Length、Type、Data)

参考:
https://zhuanlan.zhihu.com/p/687511146
TLV格式解析-CSDN博客

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐