【JT/T 808协议】808 协议开发笔记 ② ( 终端注册 | 终端注册应答 | 字符编码转换网站 )

news2025/2/23 18:37:41

文章目录

  • 一、消息头 数据
    • 1、消息头拼接
    • 2、消息 ID 字段
    • 3、消息体属性 字段
    • 4、终端手机号 字段
    • 5、终端流水号 字段
  • 二、消息体 数据
  • 三、校验码计算
  • 四、最终计算结果
  • 五、终端注册应答
    • 1、分解终端应答数据
    • 2、终端应答 消息体 数据
  • 六、字符编码转换网站





一、消息头 数据




1、消息头拼接


808 协议的消息头结构如下 :

+----------+-------------+----------------+--------+------------+----------------+
| 消息ID   | 消息体属性   | 终端手机号      | 流水号 | 总包数     | 包序号         |
| 2字节    | 2字节       | 6字节(BCD)     | 2字节  | 2字节(可选)| 2字节(可选)    |
+----------+-------------+----------------+--------+------------+----------------+

这是生成的 终端注册 消息头数据 :

消息头数据 :

01 00 00 36 01 85 11 88 88 88 00 01

参考 下图进行解析 :

在这里插入图片描述


2、消息 ID 字段


0 ~ 1 字节 是消息 ID , " 01 00 00 36 01 85 11 88 88 88 00 01 "

0x0100 是 终端注册的 消息 ID ;

在这里插入图片描述


3、消息体属性 字段


2 ~ 3 字节 是消息体属性 , " 01 00 00 36 01 85 11 88 88 88 00 01 " , 也就是 00 36 ,

将其拆解成二进制形式 为

0000 0000 0011 0110

参考下面的 位数 进行对应 ,

保留位 是 00 , 分包位 是 0 , 数据加密方式是 000 ,

消息体长度是 00 0011 0110 , 对应的十六进制为 0x36 , 十进制为 54 , 消息体长度 54 字节 ;

在这里插入图片描述


4、终端手机号 字段


4 ~ 9 字节 是 终端手机号 , " 01 00 00 36 01 85 11 88 88 88 00 01 " , 也就是 18511888888 十一位手机号 , 前面加上一个 0 ;

这是 BCD 编码 , 每个字节 高四位 表示一个数字 , 第四位表示一个数字 ;

使用 如下代码 , 可以实现 BCD 编码 到 数字字符串 之间的转换 ;

    /**
     * 读入数据时通过按位与操作将bcd编码转换成设备编号devId
     *
     * @param bcd
     * @return
     */
    public static String bcdToString(byte[] bcd) {
        // 存储转码后的字符串
        StringBuilder sb = new StringBuilder();

        // 循环数组解码 先将每个位上的
        for (int i = 0; i < bcd.length; i++) {
            // 转换低字节 十六进制的  0x0f 等于十进制的 15,二进制表示为00001111,直接取到低4位
            int low = (bcd[i] & 0x0f);
            // 转换高字节 十六进制的  0xf0 等于十进制的 240,二进制表示为11110000,右移4位的意思是取高4位
            int high = ((bcd[i] & 0xf0) >> 4);

            // 如果高字节等于0xf(二进制1111)说明是补的字节,直接抛掉
            if (high != 0xf) {
                sb.append(high);
            }

            sb.append(low);
        }
        // 返回解码字符串
        return sb.toString();
    }

    /**
     * 写出数据时将我们业务中的devId转换成bcd编码
     *
     * @param bcd
     * @return
     */
    public static byte[] strToBcd(String bcd) {
        // 获取字节数组长度
        int size = bcd.length() / 2;
        int remainder = bcd.length() % 2;

        // 存储BCD码字节
        byte[] bcdByte = new byte[size + remainder];

        // 转BCD码
        for (int i = 0; i < size; i++) {
            int high = Integer.parseInt(bcd.substring(2 * i, 2 * i + 1));
            int low = Integer.parseInt(bcd.substring(2 * i + 1, 2 * i + 2));
            bcdByte[i] = (byte) ((high << 4) | low);
        }

        // 如果存在余数,需要填F
        if (remainder > 0) {
            int low = Integer.parseInt(bcd.substring(bcd.length() - 1));
            bcdByte[bcdByte.length - 1] = (byte) ((0xf << 4) | low);
        }

        // 返回BCD码字节数组
        return bcdByte;

    }

5、终端流水号 字段


10 ~ 11 字节 是 终端流水号 , " 00 00 00 36 01 85 11 88 88 88 00 01 " ,

终端流水号 , 每次发送数据后 , 自增 1 ;





二、消息体 数据



终端注册 消息体 数据如下 :

0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00    ....BYD..2......
0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
0048 - 0063: 00 00 00 00 00 00                                  ......

参考下图进行解析 :

在这里插入图片描述

  • 0 ~ 1 字节 : 是 省域 ID , short 双字节整型 , 下面 蓝色部分是 省域 ID 数据 ;

    0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00 …BYD…2…
    0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0048 - 0063: 00 00 00 00 00 00 …

  • 2 ~ 3 字节 : 市县域 ID , short 整型 , 下面蓝色部分对应数据 ;

    0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00 …BYD…2…
    0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0048 - 0063: 00 00 00 00 00 00

  • 4 ~ 8 字节 : 5 字节数据 , 制造商编码 , 下面蓝色部分是 " BYD " 字符串对应的 ASCII 码 , 后面是 两个 0 ;

    0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00 …BYD…2…
    0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0048 - 0063: 00 00 00 00 00 00

  • 9 ~ 28 字节 : 20 字节的数据 , 终端型号 , 字符 2 对应的 ASCII 码 ; 下面蓝色字体部分 ;

    0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00 …BYD…2…
    0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0048 - 0063: 00 00 00 00 00 00

  • 29 ~ 35 字节 : 7 字节的 二进制数据 , 这里设置的是 0 ;

    0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00 …BYD…2…
    0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0048 - 0063: 00 00 00 00 00 00

  • 36 ~ 36 字节 : 1 字节的 二进制数据 , 颜色代码 ;

    0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00 …BYD…2…
    0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0048 - 0063: 00 00 00 00 00 00

  • 37 ~ 53 字节 : 17 字节的 二进制数据 , VIN 码 , 车架号 , 这里设置默认 0 ;

    0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00 …BYD…2…
    0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0048 - 0063: 00 00 00 00 00 00





三、校验码计算



终端注册

  • 消息头 :
	0000 - 0015: 01 00 00 36 01 85 11 88 88 88 00 01
  • 消息体 :
	0000 - 0015: 00 00 00 00 42 59 44 00 00 32 00 00 00 00 00 00    ....BYD..2......
    0016 - 0031: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0048 - 0063: 00 00 00 00 00 00                                  ......                                  ....~
  • 校验位 :
	0000 - 0015: E4

将 消息头 + 消息体 两个字节数组 合并后 进行校验 , 使用如下函数 从第一字节开始 进行校验 直到最后一位 ,

    /**
     * 校验位 校验码指从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。
     *
     * @return
     */
    public static byte crc(ByteBuf byteBuf) {
        ByteBuf buf = byteBuf.copy();
        byte checksum = 0;
        while (buf.readableBytes() > 0) {
            checksum ^= buf.readUnsignedByte();
        }
        return checksum;
    }




四、最终计算结果



将上述 消息头 + 消息体 + 校验位 拼装起来 ,

查看 数据中是否有 0x7e 和 0x7d , 进行转义替换 ;

出现 0x7e 的转义处理 : 0x7e <————> 0x7d 后紧跟一个 0x02;
出现 0x7d 的转义处理 : 0x7d <————> 0x7d 后紧跟一个 0x01。


最终的 终端注册数据包为 :

	0000 - 0015: 7E 01 00 00 36 01 85 11 88 88 88 00 01 00 00 00    ~...6.6.........
    0016 - 0031: 00 42 59 44 00 00 32 00 00 00 00 00 00 00 00 00    .BYD..2.........
    0032 - 0047: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0048 - 0063: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0064 - 0079: 00 00 00 E4 7E                                     ....~




五、终端注册应答



返回 终端注册应答 数据 :

	0000 - 0015: 7E 81 00 00 10 01 36 00 10 10 89 00 02 00 01 00    ~.....6.........
    0016 - 0031: BB CE CE D6 88 E2 47 AC BB 21 30 CE 39 48 7E       ..........089H~

1、分解终端应答数据


前后的 0x7E 是 标识位 ;

倒数第二位 0x48 是 校验位 ;

消息头的结构 :

+----------+-------------+----------------+--------+------------+----------------+
| 消息ID   | 消息体属性   | 终端手机号      | 流水号 | 总包数     | 包序号         |
| 2字节    | 2字节       | 6字节(BCD)     | 2字节  | 2字节(可选)| 2字节(可选)    |
+----------+-------------+----------------+--------+------------+----------------+

消息头提取出来 :

81 00 00 10 01 36 00 10 10 89 00 02

消息体数据提取出来 :

00 01 00 BB CE CE D6 88 E2 47 AC BB 21 30 CE 39 48 7E

参考下图进行解析 ;

在这里插入图片描述


2、终端应答 消息体 数据


消息体数据 :

00 01 00 BB CE CE D6 88 E2 47 AC BB 21 30 CE 39 48 7E

在这里插入图片描述

  • 00 01 是 应答 流水号 ;
  • 00 表示 终端注册 成功 ;
  • BB CE CE D6 88 E2 47 AC BB 21 30 CE 39 是 鉴权码 字符串对应的 二进制数据 ;




六、字符编码转换网站



字符编码转换网站 :

  • GBK 编码转换
  • UTF-8 编码转换
  • URL 编码转换

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2304035.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

51单片机学习之旅——定时器

打开软件 1与其它等于其它&#xff0c;0与其它等于0 1或其它等于1&#xff0c;0或其它等于其它 TMODTMOD&0xF0;//0xF01111 0000进行与操作&#xff0c;高四位保持&#xff0c;低四位清零&#xff0c;高四位定时器1&#xff0c;低四位定时器0 TMODTMOD|0x01;//0x010000 0…

hot100_139. 单词拆分

hot100_139. 单词拆分 思路 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意&#xff1a;不要求字典中出现的单词全部都使用&#xff0c;并且字典中的单词可以重复使用。 示例 1&#xff1a; 输入:…

SQLMesh 系列教程7- 详解 seed 模型

SQLMesh 是一个强大的数据建模和管道管理工具&#xff0c;允许用户通过 SQL 语句定义数据模型并进行版本控制。Seed 模型是 SQLMesh 中的一种特殊模型&#xff0c;主要用于初始化和填充基础数据集。它通常包含静态数据&#xff0c;如参考数据和配置数据&#xff0c;旨在为后续的…

windows11那些事

一.windows11简介 Windows11是‌微软公司于2021年发布的桌面端操作系统&#xff0c;它带来了许多新的功能和改进&#xff0c;旨在提升用户体验和工作效率。以下是一些关于Windows 11的基础知识和使用技巧&#xff1a; ‌‌通用搜索&#xff1a;通过任务栏上的搜索或按Windows…

VividTalk:南京大学、阿里巴巴等机构联合研发的开源3D说话人生成框架

目录 一、前言二、项目概述三、技术架构四、优势特点五、性能评估六、应用场景七、结论与展望 一、前言 在当今人工智能飞速发展的时代&#xff0c;人机交互的方式正不断创新和优化。VividTalk作为南京大学、阿里巴巴、字节跳动和南开大学联合开发的一项开创性技术&#xff0c…

pyside6学习专栏(三):自定义QLabel标签扩展类QLabelEx

标签是界面设计中最常用的控件&#xff0c;本文演示了如何基于PySide6的QLabex控件类扩展定义QLabelEX类&#xff0c;以实现更少的编码完成各种图像、彩色文本、动画的加载和显示&#xff0c;丰富界面显示 本示例演示了QLabel和其扩展类QLabelEx分别显示文本、图像、动画的使用…

后“智驾平权”时代,谁为安全冗余和体验升级“买单”

线控底盘&#xff0c;正在成为新势力争夺下一个技术普及红利的新赛点。 尤其是进入2025年&#xff0c;比亚迪、长安等一线传统自主品牌率先开启高阶智驾的普及战&#xff0c;加上此前已经普及的智能座舱&#xff0c;舱驾智能的「科技平权」进一步加速行业启动「线控底盘」上车窗…

springboot408-基于Java的樱洵宾馆住宿管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…

EasyRTC:基于WebRTC与P2P技术,开启智能硬件音视频交互的全新时代

在数字化浪潮的席卷下&#xff0c;智能硬件已成为我们日常生活的重要组成部分&#xff0c;从智能家居到智能穿戴&#xff0c;从工业物联网到远程协作&#xff0c;设备间的互联互通已成为不可或缺的趋势。然而&#xff0c;高效、低延迟且稳定的音视频交互一直是智能硬件领域亟待…

鸿蒙NEXT应用App测试-通用测试

注意&#xff1a;大家记得学完通用测试记得再学鸿蒙专项测试 https://blog.csdn.net/weixin_51166786/article/details/145768653 注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章…

transfmer学习认识

整体架构 1.自注意机制 1.1.softmax 在机器学习和深度学习中&#xff0c;softmax 函数是一个常用的激活函数&#xff0c;用于将一个向量转换为一个概率分布。softmax 函数的公式如下&#xff1a; ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/35c158988402498ba6…

人工智能(AI)的不同维度分类

人工智能(AI)的分类 对机器学习进行分类的方式多种多样&#xff0c;可以根据算法的特性、学习方式、任务类型等不同维度进行分类这些分类都不是互斥的&#xff1a; 1、按数据模态不同:图像&#xff0c;文本&#xff0c;语音&#xff0c;多态等 2、按目标函数不同:判别式模型…

三、linux字符驱动详解

在上一节完成NFS开发环境的搭建后&#xff0c;本节将探讨Linux字符设备驱动的开发。字符设备驱动作为Linux内核的重要组成部分&#xff0c;主要负责管理与字符设备&#xff08;如串口、键盘等&#xff09;的交互&#xff0c;并为用户空间程序提供统一的读写操作接口。 驱动代码…

谈谈 ES 6.8 到 7.10 的功能变迁(1)- 性能优化篇

前言 ES 7.10 可能是现在比较常见的 ES 版本。但是对于一些相迭代比较慢的早期业务系统来说&#xff0c;ES 6.8 是一个名副其实的“钉子户”。 借着工作内升级调研的任务东风&#xff0c;我整理从 ES 6.8 到 ES 7.10 ELastic 重点列出的新增功能和优化内容。将分为 6 个篇幅给…

我用Ai学Android Jetpack Compose之LinearProgressIndicator

本篇&#xff0c;我们来学习LinearProgressIndicator&#xff0c;答案来自 通义千问 Q:我想学习LinearProgressIndicator&#xff0c;麻烦你介绍一下 当然可以&#xff01;LinearProgressIndicator 是 Jetpack Compose 中的一个组件&#xff0c;用于显示线性进度条。它非常适…

在群晖上使用Docker安装思源笔记

​​ 最近一段时间&#xff0c;docker的镜像地址都失效了&#xff0c;在群晖系统中&#xff0c;无论是早期版本的docker&#xff0c;还是最新版本中的Container Manager&#xff0c;注册表中都无法链接到docker的镜像&#xff0c;于是&#xff0c;就花了点时间查找资料&#x…

【废物研究生刷算法】字符串

文章目录 1. 反转字符串2. 替换数字3. 反转字符串中的单词4. 右旋字符串总结1、字符串处理函数2、字符串切片 如果使用python处理字符串&#xff0c;有很多py内置的函数可以使用&#xff0c;主要还是记住这些处理方法。 1. 反转字符串 class Solution:def reverseStr(self, s, …

idea-代码补全快捷键

文章目录 前言idea-代码补全快捷键1. 基本补全2. 类型匹配补全3. 后缀补全4. 代码补全 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;…

我们来学人工智能 -- DeepSeek客户端

DeepSeek客户端 题记使用后记系列文章 题记 我选择了 Cherry Studio是国内产品由CherryHQ团队开源是一个平台在这里&#xff0c;有豆包、kimi、通义千问的入口当然&#xff0c;最主要是作为大模型的UI正如标题&#xff0c;这里&#xff0c;作为DeepSeep的客户端 使用 下载本…

洛谷 P1102 A-B 数对(详解)c++

题目链接&#xff1a;P1102 A-B 数对 - 洛谷 1.题目分析 2.算法原理 解法一&#xff1a;暴力 - 两层for循环 因为这道题需要你在数组中找出来两个数&#xff0c;让这两个数的差等于定值C就可以了&#xff0c;一层for循环枚举A第二层for循环枚举B&#xff0c;求一下看是否等于…