【JT/T 808协议】808 协议开发笔记 ② ( 终端注册 | 终端注册应答 | 字符编码转换网站 )
文章目录
- 一、消息头 数据
- 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);}// 如果存在余数,需要填Fif (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 编码转换
相关文章:
【JT/T 808协议】808 协议开发笔记 ② ( 终端注册 | 终端注册应答 | 字符编码转换网站 )
文章目录 一、消息头 数据1、消息头拼接2、消息 ID 字段3、消息体属性 字段4、终端手机号 字段5、终端流水号 字段 二、消息体 数据三、校验码计算四、最终计算结果五、终端注册应答1、分解终端应答数据2、终端应答 消息体 数据 六、字符编码转换网站 一、消息头 数据 1、消息头…...
番茄工作法html实现
对比了deepseek-r1-online和本地部署的14b的版本,输出的输出的html页面。 在线满血版的功能比较强大,可以一次完成所有要求。14b版本的功能有一些欠缺,但是基本功能也是写了出来了。 input write a html named Pomodoro-clock which “hel…...
抓包工具 wireshark
1.什么是抓包工具 抓包工具是什么?-CSDN博客 2.wireshark的安装 【抓包工具】win 10 / win 11:WireShark 下载、安装、使用_windows抓包工具-CSDN博客 3.wireshark的基础操作 Wireshark零基础使用教程(超详细) - 元宇宙-Meta…...
51单片机学习之旅——定时器
打开软件 1与其它等于其它,0与其它等于0 1或其它等于1,0或其它等于其它 TMODTMOD&0xF0;//0xF01111 0000进行与操作,高四位保持,低四位清零,高四位定时器1,低四位定时器0 TMODTMOD|0x01;//0x010000 0…...
hot100_139. 单词拆分
hot100_139. 单词拆分 思路 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 示例 1: 输入:…...
Linux firewalld 常用命令
本文参考RedHat官网文章How to configure a firewall on Linux with firewalld。 Firewalld 是守护进程名,对应命令为firewall-cmd。帮助详见以下命令: $ firewall-cmd --helpUsage: firewall-cmd [OPTIONS...]General Options-h, --help Pr…...
《网络安全入门实战手册》
0经验转行网络安全,个人分享一下学习中总结的文档,以下为目录可以点击标题看对应文章,欢迎评论区讨论,后期会发更多安全相关的学习资料等。希望跟大家一起进步。 第1章:网络安全基础知识 1、什么是网络安全ÿ…...
SQLMesh 系列教程7- 详解 seed 模型
SQLMesh 是一个强大的数据建模和管道管理工具,允许用户通过 SQL 语句定义数据模型并进行版本控制。Seed 模型是 SQLMesh 中的一种特殊模型,主要用于初始化和填充基础数据集。它通常包含静态数据,如参考数据和配置数据,旨在为后续的…...
windows11那些事
一.windows11简介 Windows11是微软公司于2021年发布的桌面端操作系统,它带来了许多新的功能和改进,旨在提升用户体验和工作效率。以下是一些关于Windows 11的基础知识和使用技巧: 通用搜索:通过任务栏上的搜索或按Windows…...
VividTalk:南京大学、阿里巴巴等机构联合研发的开源3D说话人生成框架
目录 一、前言二、项目概述三、技术架构四、优势特点五、性能评估六、应用场景七、结论与展望 一、前言 在当今人工智能飞速发展的时代,人机交互的方式正不断创新和优化。VividTalk作为南京大学、阿里巴巴、字节跳动和南开大学联合开发的一项开创性技术,…...
pyside6学习专栏(三):自定义QLabel标签扩展类QLabelEx
标签是界面设计中最常用的控件,本文演示了如何基于PySide6的QLabex控件类扩展定义QLabelEX类,以实现更少的编码完成各种图像、彩色文本、动画的加载和显示,丰富界面显示 本示例演示了QLabel和其扩展类QLabelEx分别显示文本、图像、动画的使用…...
后“智驾平权”时代,谁为安全冗余和体验升级“买单”
线控底盘,正在成为新势力争夺下一个技术普及红利的新赛点。 尤其是进入2025年,比亚迪、长安等一线传统自主品牌率先开启高阶智驾的普及战,加上此前已经普及的智能座舱,舱驾智能的「科技平权」进一步加速行业启动「线控底盘」上车窗…...
springboot408-基于Java的樱洵宾馆住宿管理系统(源码+数据库+纯前后端分离+部署讲解等)
💕💕作者: 爱笑学姐 💕💕个人简介:十年Java,Python美女程序员一枚,精通计算机专业前后端各类框架。 💕💕各类成品Java毕设 。javaweb,ssm…...
C语言中 %* 的用法总结
C语言中 %* 的用法总结 一、scanf 中的 %* 作用:跳过输入字段,读取数据但不存储到变量。语法:%*[格式] 示例格式:%*d(跳过一个整数)、%*s(跳过一个字符串)。 适用场景:…...
EasyRTC:基于WebRTC与P2P技术,开启智能硬件音视频交互的全新时代
在数字化浪潮的席卷下,智能硬件已成为我们日常生活的重要组成部分,从智能家居到智能穿戴,从工业物联网到远程协作,设备间的互联互通已成为不可或缺的趋势。然而,高效、低延迟且稳定的音视频交互一直是智能硬件领域亟待…...
鸿蒙NEXT应用App测试-通用测试
注意:大家记得学完通用测试记得再学鸿蒙专项测试 https://blog.csdn.net/weixin_51166786/article/details/145768653 注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章…...
transfmer学习认识
整体架构 1.自注意机制 1.1.softmax 在机器学习和深度学习中,softmax 函数是一个常用的激活函数,用于将一个向量转换为一个概率分布。softmax 函数的公式如下: …...
人工智能(AI)的不同维度分类
人工智能(AI)的分类 对机器学习进行分类的方式多种多样,可以根据算法的特性、学习方式、任务类型等不同维度进行分类这些分类都不是互斥的: 1、按数据模态不同:图像,文本,语音,多态等 2、按目标函数不同:判别式模型…...
三、linux字符驱动详解
在上一节完成NFS开发环境的搭建后,本节将探讨Linux字符设备驱动的开发。字符设备驱动作为Linux内核的重要组成部分,主要负责管理与字符设备(如串口、键盘等)的交互,并为用户空间程序提供统一的读写操作接口。 驱动代码…...
谈谈 ES 6.8 到 7.10 的功能变迁(1)- 性能优化篇
前言 ES 7.10 可能是现在比较常见的 ES 版本。但是对于一些相迭代比较慢的早期业务系统来说,ES 6.8 是一个名副其实的“钉子户”。 借着工作内升级调研的任务东风,我整理从 ES 6.8 到 ES 7.10 ELastic 重点列出的新增功能和优化内容。将分为 6 个篇幅给…...
我用Ai学Android Jetpack Compose之LinearProgressIndicator
本篇,我们来学习LinearProgressIndicator,答案来自 通义千问 Q:我想学习LinearProgressIndicator,麻烦你介绍一下 当然可以!LinearProgressIndicator 是 Jetpack Compose 中的一个组件,用于显示线性进度条。它非常适…...
代码随想录算法训练营day40(补0208)
买卖股票专栏 1.买卖股票最佳时机 贪心法,好想 题目 121. 买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖…...
在群晖上使用Docker安装思源笔记
最近一段时间,docker的镜像地址都失效了,在群晖系统中,无论是早期版本的docker,还是最新版本中的Container Manager,注册表中都无法链接到docker的镜像,于是,就花了点时间查找资料&#x…...
【废物研究生刷算法】字符串
文章目录 1. 反转字符串2. 替换数字3. 反转字符串中的单词4. 右旋字符串总结1、字符串处理函数2、字符串切片 如果使用python处理字符串,有很多py内置的函数可以使用,主要还是记住这些处理方法。 1. 反转字符串 class Solution:def reverseStr(self, s, …...
断开ssh连接程序继续运行
在使用 SSH 远程连接服务器时,我们常希望在断开连接后仍然让程序继续运行,以下是几种常见的方法: 1. 使用 screen 或 tmux screen 和 tmux 是两款非常强大的终端复用工具,它们允许你在后台运行会话,即使断开 SSH 连接…...
Kafka客户端连接服务端异常 Can‘t resolve address: VM-12-16-centos:9092
前置条件: 已在CentOs上搭建好kafka节点服务器,已启动kafka服务已在Springboot项目中引入kafka客户端配置,kafka.bootstrap-serverip:port,并启动客户端服务 异常过程: 在客户端Springboot服务启动过程,控…...
视频mp4垂直拼接 水平拼接
视频mp4垂直拼接 水平拼接 pinjie_v.py import imageio import numpy as np import os import cv2def pinjie_v(dir1,dir2,out_dir):os.makedirs(out_dir, exist_okTrue)# 获取目录下的所有视频文件video_files_1 [f for f in os.listdir(dir1) if f.endswith(.mp4)]video_fi…...
idea-代码补全快捷键
文章目录 前言idea-代码补全快捷键1. 基本补全2. 类型匹配补全3. 后缀补全4. 代码补全 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。 而且听说点赞的人每天的运气都不会太差,…...
Transformer为什么需要多头注意力(Multi-Head Attention)?如果没有多头会怎么样?
直接回答 关键点: Transformer 中的多头注意力(Multi-Head Attention)允许模型同时关注输入数据的不同方面,提升性能。 如果没有多头,模型可能无法捕捉复杂关系,表现会下降。 什么是多头注意力ÿ…...
