文章目錄
- 一、消息頭 數據
- 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: 01 00 00 36 01 85 11 88 88 88 00 01 00 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 編碼轉換