【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、消息头…...
github配置sshkey
使用命令生成sshkey ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 依此会要求输入以下信息,可以使用默认值 设置保存密钥的路径 设置SSH密钥密码(备注:空内容表示不设置SSH密钥密码) 再次确认SSH密钥密…...
Java数据结构第十二期:走进二叉树的奇妙世界(一)
专栏:数据结构(Java版) 个人主页:手握风云 目录 一、树型结构 1.1. 树的定义 1.2. 树的基本概念 1.3. 树的表示形式 二、二叉树 2.1. 概念 2.2. 两种特殊的二叉树 2.3. 二叉树的性质 2.4. 二叉树的存储 三、二叉树的基本操作 一、树型结构 1.…...
Web的增删改查
准备环境 1. 添加web 点击项目右键——>选择**添加框架**选择**web应用程序** 2.创建lib目录 在web应用程序的**WEB-INF目录下**创建lib目录添加jar包(5个)解压:右键——>选择**添加库** 3.创建Dao层 在src目录下创建包com.zmq在该包下创建dao层添加工具…...
Java 前后端时间格式转换
在 Web 开发里,时间格式处理既常见又关键。由于前端和后端对时间的表示、处理方式存在差异,熟练掌握时间格式的转换方法就显得尤为重要。这篇文章会深入探讨 Java 前后端时间格式转换的相关知识,特别是 Java 时间转换的多种方式,其…...
【用deepseek和chatgpt做算法竞赛】——还得DeepSeek来 -Minimum Cost Trees_5
往期 【用deepseek和chatgpt做算法竞赛】——华为算法精英实战营第十九期-Minimum Cost Trees_0:介绍了题目和背景【用deepseek和chatgpt做算法竞赛】——华为算法精英实战营第十九期-Minimum Cost Trees_1:题目输入的格式说明,选择了邻接表…...
C++ 互斥锁的使用
mutex std::mutex 是C标准库中用于线程同步的互斥锁机制,主要用于保护共享资源,避免多个线程同时访问导致的竞态条件。 它提供了以下功能: 加锁(lock):阻塞当前线程,直到获取锁。 解锁&#…...
【Elasticsearch】Retrieve inner hits获取嵌套查询的具体的嵌套文档来源,以及父子文档的来源
Retrieve inner hits 是 Elasticsearch 中的一个功能,用于在嵌套查询或父子查询中,返回导致主文档匹配的具体嵌套对象或子/父文档的详细信息,帮助用户更直观地理解查询结果的来源。 在 Elasticsearch 中,Retrieve inner hits是一…...
C语言中的typedef关键字详解
C语言中的typedef关键字详解 在C语言编程中,typedef 关键字是一个非常实用的特性,它可以帮助我们创建新的类型名,从而简化代码,提高可读性。本文将详细解析typedef的使用方法、场景以及注意事项。 1. typedef简介 typedef 是Ty…...
怎麼利用靜態ISP住宅代理在指紋流覽器中管理社媒帳號?
靜態ISP住宅代理是一種基於真實住宅IP的代理服務。這類代理IP通常由互聯網服務提供商(ISP)分配,具有非常高的真實性,與普通數據中心代理相比,更不容易被平臺檢測到為“虛假IP”或“代理IP”,靜態ISP住宅代理…...
【多语言生态篇一】【DeepSeek×Java:Spring Boot微服务集成全栈指南 】
(手把手带你从零实现AI能力调用,万字长文预警,建议收藏实操) 一、环境准备:别输在起跑线上 1.1 硬件软件全家桶 JDK版本:必须 ≥17(Spring Boot 3.2+强制要求,低版本直接报错)IDE推荐:IntelliJ IDEA终极版(社区版缺Spring AI插件支持)构建工具:Maven 3.9+ / Grad…...
IOS UITextField 无法隐藏键盘问题
设置UITextField 键盘按钮返回键为“完成”,即return key 设置done .m代码设置代理 //设置代理协议 UITextFieldDelegate, self.mobileTextField.delegate self; ///点击完成键隐藏键盘 - (BOOL)textFieldShouldReturn:(UITextField *)textField{//取…...
einops测试
文章目录 1. einops2. code3. pytorch 1. einops einops 主要是通过爱因斯坦标记法来处理张量矩阵的库,让矩阵处理上非常简单。 conda : conda install conda-forge::einopspython: 2. code import torch import torch.nn as nn import torch.nn.functional as…...
25轻化工程研究生复试面试问题汇总 轻化工程专业知识问题很全! 轻化工程复试全流程攻略 轻化工程考研复试真题汇总
轻化工程复试心里没谱?学姐带你玩转面试准备! 是不是总觉得老师会问些刁钻问题?别焦虑!其实轻化工程复试套路就那些,看完这篇攻略直接掌握复试通关密码!文中有重点面试题可直接背~ 目录 一、这些行为赶紧避…...
小米路由器 AX3000T 降级后无法正常使用,解决办法
问题描述 买了个 AX3000T 路由器,想安装 OpenWRT 或者 安装 Clash 使用,看教程说是需要降级到 v1.0.47 版本。 结果刷机之后路由器无法打开了,一直黄灯亮,中间灭一下,又是黄灯长亮,没有 WIFI 没有连接。以…...
qt5实现表盘的旋转效果,通过提升QLabel类
因为工作需要,需要实现温度的表盘展示效果 实现思路: 通过提示声QLabel控价类,实现报盘的旋转和展示效果 1. 编写一个QLabel的类MyQLabel,实现两个方法 1. void paintEvent(QPaintEvent *event); //重绘函数 2. void valueChanged(int va…...
【HeadFirst系列之HeadFirst设计模式】第7天之命令模式:封装请求,轻松实现解耦!
命令模式:封装请求,轻松实现解耦! 大家好!今天我们来聊聊设计模式中的命令模式(Command Pattern)。如果你曾经需要将请求封装成对象,或者希望实现请求的撤销、重做等功能,那么命令模…...
HTTPS(下)
主要讲加密算法RSA,ECDHE TLS的握手涉及四次通信,根据不同的密钥交换算法,TLS 握手流程也会不一样的,现在常用的密钥交换算法有两种:RSA 算法和 ECDHE 算法 正常情况下,需要先TCP三次握手后进行TLS四次握手…...
vue2 和 vue3 中 computer 计算属性的用法
Vue 2 中的 computed 在 Vue 2 中,计算属性是响应式的,并且基于 getter 进行缓存,只有依赖的响应式数据发生变化时才会重新计算。 基本用法 <template><div><p>原始消息:{{ message }}</p><p>反…...
【STM32学习】标准库实现STM32 ADC采集1路、2路、多路
目录 ADC采集 ADC配置步骤 STM32F103C8T6的ADC 输入通道 编辑 1路ADC(A4 ADC 通道4) 1路ADC源码代码链接: 2路ADC(A4 ADC 通道4、A5 ADC 通道5)基于DMA实现 多路ADC实现采集 ADC采集 ADC配置步骤 使能GPIO…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...
