前言
通讯方式TCP:每个设备建立一个TCP长连接,无数据时需要60秒发送心跳包,有数据时按要求发送数据:
数据包结构:
7E消息头(36Bytes)消息体CRC7E
*消息头消息体中出现0x7E 需要转化为0x7D 0x02 , 出现0x7D 转化为 0x7D 0x01
*需要使用消息体SM4加密,统一使用密文zhgl(7a68676c000000000000000000000000)
*CRC验证消息头和消息体内容
1加密消息体 2 CRC 3转化
SM4加密:java sm4国密算法加密解密 - Marydon - 博客园
需要添加的功能模块:
在数据库通道信息中,在发送过程中添加设备编号。无需发送的设备编号为空字符串。
读取信息时,读取设备编号的内存,并添加是否已被识别成功socket的标记位。
当设备收集数据时,判断通道是否需要发送数据,如果需要发送,计算后进入发送过程。
需要添加的数据模块:
添加通道信息和发送数据socket对应的MAP
添加通道信息和链表对应于需要额外发布的数据MAP
发送数据流程:
(未注册socket)
- 发送注册包注册,等待注册包回复
- 发送鉴权包,等待鉴权包回复,成功保持连接发送后的数据,失败时断开连接,等待30秒重新连接发送。
(已注册socket)
- 发送传感器数据信息并等待回复。如果回复成功,则继续;如果失败,将数据存储在缓冲中10秒后继续发送。如果连续三次断开连接,下次需要发送数据时重新连接
- 所有失败的数据包都存储在缓冲数据列中,数据成功发送后依次发送。
0x07 命令码 消息体长度(数据包为:0x000x000x000x12)0x01 0x01 0x01 设备编号(设备编号)excel中的编号) 时间(YYYYMMDDhhmmss共7位:2020-07-1517:30:35表示为0x14 0x14 0x07 0x0F 0x11 0x1E 0x23)
命令码:0x01
0x16(或0x19) YSB(补两个空间) AIOTYB(补0x00补足20位),设备编号(设备编号)excel中的编号) 0x405C82703AFB7E91(经度)0x404178C7E28240B8(纬度)ip(ipV4 4位后面补0x20补足16位) 0x00 0x3C 0x00 0x00 0x00 0x32 0x30 0x32 0x31 0x30 0x01 0x30 0x01
平台返回鉴权码:
0x7E 命令字 鉴权码 0x7E
命令码:0x02
消息体平台返回鉴权码:补0不到32位x20补20个空格
命令码:0x03
消息体为空
命令码:0x16
数据包主内容:0x00 0x01 P001 Z 0000000000
0x00 0x01为2个byte数值,红色部分为字符串需要再转化为byte再输出
P001:传感器编号(固定值)
Z:正数,如果结果为负数则写F
0000000000:挠度值(10个字节)0000000000-9999999999表示00000.00000mm到99999.99999mm
命令码0x19
数据包内容:0x00 0x01 Y001 Z 0000000000
Y001:传感器编号(固定值)
Z:正数,如果结果为负数则写F
0000000000:挠度值(10个字节)0000000000-9999999999表示00000.00000με到99999.99999με
package TCPserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import com.AIOT.utils.Sm4Util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class SocketUtil {
//public static Map<String,Map<String,NumberNowDate>> dateMap = new HashMap<String,Map<String,NumberNowDate>>(); //nowData ->NumberDate
public static Map<String,Integer> numberMap = new HashMap<String,Integer>();//设备编号->消息流水
public static final String Y_M_D_H_M_S = "yyyyMMdd HHmmss";
public final static byte [] packge ={0x5a,0x20,0x00,0x11,0x11};//0注册包1鉴权包2心跳包3水准消息体4应变消息体
public final static byte [] codePackge ={0x01,0x02,0x03,0x16,0x19};//同上 命令码
public static byte [] codeLength={0x00,0x00,0x00,0x00};
public static byte [] codeLength3={0x01,0x01,0x01};//00不加密 01加密
public static byte [] typePackege={0x1,0x19};//0水准1应变
public static String [] flag ={"Z","F"};//Z正数F负数
public static Map<String, Socket> ipMap = new HashMap<String, Socket>();//通道信息对应socket
/**
* 消息头
*
* @param flag
* @param EquipmentNumber
* @return
* @throws Exception
*/
public static byte[] getMessageHeader(int flag, String EquipmentNumber) {
byte[] head = new byte[36];
codeLength[3] = packge[flag];
byte[] code2 = codeLength;
byte[] code1 = { 0x07, codePackge[flag], code2[0], code2[1], code2[2], code2[3], codeLength3[0], codeLength3[1],
codeLength3[2] };// code1(code2)共9
byte[] code4 = uint16ToBytes(getDowDateNum(EquipmentNumber));// 流水号
byte[] code5 = EquipmentNumber.getBytes();// 设备编号18
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DATE);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
byte[] code6 = { (byte) (year / 100), (byte) (year % 100), (byte) month, (byte) day, (byte) hour, (byte) min,
(byte) sec };
System.arraycopy(code1, 0, head, 0, 9);
System.arraycopy(code4, 0, head, 9, 2);
System.arraycopy(code5, 0, head, 11, 18);
System.arraycopy(code6, 0, head, 29, 7);
return head;
}
/**
* 注册包消息体
* @param flag
* @param EquipmentNumber
* @return
*/
public static byte[] getRegistrationPackageMessageBody(String EquipmentNumber){
byte[] head = new byte[90];
byte [] code1 = {0x07,'Y','S','B',' ',' ','A','I','O','T','Y','B',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};//26
byte [] code2 = EquipmentNumber.getBytes();//设备编号18
byte [] code3 = {0x40,0x5C,(byte) 0x82,0x70,0x3A,(byte) 0xFB,0x7E,(byte) 0x91,0x40,0x41,0x78,(byte) 0xC7,(byte) 0xE2,(byte) 0x82,0x40,(byte) 0xB8};//16
//String ip = getIP();
String ip = "0.0.0.0";
String[] split = ip.split("\\.");
byte [] code4 ={0x00,(byte) Integer.parseInt(split[0]),(byte) Integer.parseInt(split[1]),(byte) Integer.parseInt(split[2]),(byte) Integer.parseInt(split[3]),' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0x00,0x3C,0x00,0x00,0x00,0x32,0x30,0x32,0x31,0x30,0x31,0x30,0x31};//30
System.arraycopy(code1, 0 , head , 0, 26);
System.arraycopy(code2, 0 , head , 26, 18);
System.arraycopy(code3, 0 , head , 44,16);
System.arraycopy(code4, 0 , head , 60,30);
return head;
}
/**
* 鉴权包消息体
* @return
* @throws Exception
*/
public static byte[] getAuthenticationPacketMessageBody(byte[] codeToken,int flag,String EquipmentNumber) throws Exception{
byte[] messageHeader = getMessageHeader(flag, EquipmentNumber);//获得消息头
byte[] key = {0x7a,0x68,0x67,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
byte[] cipher = Sm4Util.encryptEcb(key, codeToken);//加密后的消息体
byte[] addBytes = addBytes(messageHeader, cipher);//合并消息头消息体
int crc2 = CRC16.calcCrc16(addBytes);//CRC校验
byte[] uint16ToBytes = uint16ToBytes(crc2);
byte[] addAllBytes = addBytes(addBytes,uint16ToBytes);
byte[] index = check7DGetNewArray(addAllBytes);
byte[] index1 = check7EGetNewArray(index);
byte[] startArray = {0x7E};
byte[] endArray = {0x7E};
byte[] endAllBytes = addAllBytes(startArray,index1,endArray);
return endAllBytes;
}
/**
* 心跳包消息体
* @throws Exception
*/
public static byte[] sendHeartbeatPacketMessageBody(int flag,String EquipmentNumber){
byte[] messageHeader = getMessageHeader(flag, EquipmentNumber);//获得消息头
int crc2 = CRC16.calcCrc16(messageHeader);//CRC校验
byte[] uint16ToBytes = uint16ToBytes(crc2);
byte[] addAllBytes = addBytes(messageHeader, uint16ToBytes);
byte[] index = check7DGetNewArray(addAllBytes);
byte[] index1 = check7EGetNewArray(index);
byte[] startArray = {0x7E};
byte[] endArray = {0x7E};
byte[] endAllBytes = addAllBytes(startArray,index1,endArray);
return endAllBytes;
}
/**
* 发送完整的注册包
* @param head
* @param flag
* @param EquipmentNumber
* @return
* @throws Exception
*/
public static byte[] getRegistrationPackageAllMessage(byte[] head,int flag,String EquipmentNumber) throws Exception{
byte[] registrationPackageMessageBody = getRegistrationPackageMessageBody(EquipmentNumber);//获取消息体
//消息体加密
// 自定义的32位16进制密钥
byte[] key = {0x7a,0x68,0x67,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
byte[] cipher = Sm4Util.encryptEcb(key, registrationPackageMessageBody);//加密后的消息体
Sm4Util.decryptEcb(key, cipher);
byte[] addBytes = addBytes(head, cipher);//合并消息头消息体
int crc2 = CRC16.calcCrc16(addBytes);//CRC校验
byte[] uint16ToBytes = uint16ToBytes(crc2);
byte[] addAllBytes = addBytes(addBytes, uint16ToBytes);
byte[] index = check7DGetNewArray(addAllBytes);
byte[] index1 = check7EGetNewArray(index);
byte[] startArray = {0x7E};
byte[] endArray = {0x7E};
byte[] endAllBytes = addAllBytes(startArray,index1,endArray);
return endAllBytes;
}
/**
* 水准消息体
* @throws Exception
*/
public static byte[] sendSqvMessageBody(String EquipmentNumber,double data) throws Exception{
byte[] head = getMessageHeader(3, EquipmentNumber);//获得消息头
byte[] result = new byte[17];
byte[] code0 ={0x00,0x01};
String str ="P001";
if(data>0.0 || data==0.0){
str+=flag[0];
}else{
str+=flag[1];
}
String formate=String.format("%05d",Integer.parseInt(String.valueOf(data).split("\\.")[0]));
str+=formate;
String formate1=String.format("%.5f",data);
formate1=formate1.split("\\.")[1];
str+=formate1;
byte[] code1 = str.getBytes();
System.arraycopy(code0, 0 , result , 0, 2);
System.arraycopy(code1, 0 , result , 2, 15);
// 自定义的32位16进制密钥
byte[] key = {0x7a,0x68,0x67,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
byte[] cipher = Sm4Util.encryptEcb(key, result);//加密后的消息体
byte[] addBytes = addBytes(head, cipher);//合并消息头数据消息体
int crc2 = CRC16.calcCrc16(addBytes);//CRC校验
byte[] uint16ToBytes = uint16ToBytes(crc2);
byte[] addAllBytes = addBytes(addBytes, uint16ToBytes);
byte[] index = check7DGetNewArray(addAllBytes);
byte[] index1 = check7EGetNewArray(index);
byte[] startArray = {0x7E};
byte[] endArray = {0x7E};
byte[] endAllBytes = addAllBytes(startArray,index1,endArray);
return endAllBytes;
}
public static byte[] sendDvwMessageBoby(String EquipmentNumber,double data) throws Exception{
byte[] head = getMessageHeader(4, EquipmentNumber);//获得消息头
byte[] result = new byte[17];
byte[] code0 ={0x00,0x01};
String str ="Y001";
if(data>0.0 || data==0.0){
str+=flag[0];
}else{
str+=flag[1];
}
String formate=String.format("%05d",Integer.parseInt(String.valueOf(data).split("\\.")[0]));
str+=formate;
String formate1=String.format("%.5f",data);
formate1=formate1.split("\\.")[1];
str+=formate1;
byte[] code1 = str.getBytes();
System.arraycopy(code0, 0 , result , 0, 2);
System.arraycopy(code1, 0 , result , 2, 15);
// 自定义的32位16进制密钥
byte[] key = {0x7a,0x68,0x67,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
byte[] cipher = Sm4Util.encryptEcb(key, result);//加密后的消息体
byte[] addBytes = addBytes(head, cipher);//合并消息头数据消息体
int crc2 = CRC16.calcCrc16(addBytes);//CRC校验
byte[] uint16ToBytes = uint16ToBytes(crc2);
byte[] addAllBytes = addBytes(addBytes, uint16ToBytes);
byte[] index = check7DGetNewArray(addAllBytes);
byte[] index1 = check7EGetNewArray(index);
byte[] startArray = {0x7E};
byte[] endArray = {0x7E};
byte[] endAllBytes = addAllBytes(startArray,index1,endArray);
return endAllBytes;
}
//测试
public static void main(String[] args) throws Exception {
//sendSqvMessageBody(90.2323);
/*byte code =0x1;
String number ="410122G107QLS00001";
byte[] registrationPackageMessageBody = getRegistrationPackageMessageBody(0, number);
System.out.println(registrationPackageMessageBody);*/
//测试获取注册包
String number ="410122G107QLS00016";
for (int i = 0; i < 6; i++) {
int dowDateNum = getDowDateNum("410122G107QLS00015");
//System.out.println("累加的流水编号:"+dowDateNum);
}
byte[] messageHeader = getMessageHeader(0, number);//消息头
System.out.println("消息头长度"+messageHeader.length);
byte[] endAllBytes =getRegistrationPackageAllMessage(messageHeader, 0, number);
/*byte[] endAllBytes = sendHeartbeatPacketMessageBody(2, number);//心跳包
* */
/*byte[] endAllBytes =getAuthenticationPacketMessageBody(1, number);//鉴权包
*/
System.out.println("注册包数据长度"+endAllBytes.length);
ByteConvert.printHexString(endAllBytes);
try
{
Socket socket = new Socket("xxxx", xxx);
//得到一个输出流,用于向服务器发送数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write(endAllBytes);
//刷新缓冲
outputStream.flush();
//得到一个输入流,用于接收服务器响应的数据
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1]; // 一次读取一个byte
byte[] bytes1 = new byte[103]; //
String info = "";
byte[] keyToken=new byte[32];//鉴权码
int state = 0;
int count = 0;
byte[] sendSqvMessageBody=null;
while (true)
{
if (inputStream.available() > 0)
{
if(state == 0)
{
inputStream.read(bytes1);
String hexStr = ByteArrayToHexStr(bytes);
info += HexStrToStr(hexStr);
//已经读完
if (inputStream.available() == 0)
{
if(bytes1[1]==0x01){
System.arraycopy(bytes1,2 , keyToken , 0, 32);
}
ByteConvert.printHexString(keyToken);
ByteConvert.printHexString(bytes1);
byte[] authenticationPacketMessageBody = getAuthenticationPacketMessageBody(keyToken, 1, number);
System.out.println("发送鉴权包");
ByteConvert.printHexString(authenticationPacketMessageBody);
outputStream.write(authenticationPacketMessageBody);
//刷新缓冲
outputStream.flush();
state =1;
}
}
else if(state == 1)
{
System.out.println("鉴权包回复");
inputStream.read(bytes1);
String hexStr1 = ByteArrayToHexStr(bytes);
info += HexStrToStr(hexStr1);
ByteConvert.printHexString(bytes1);
/*sendSqvMessageBody = sendSqvMessageBody(number, 5.23);//水准仪
*/ sendSqvMessageBody = sendDvwMessageBoby(number, 10.25);//应变
/*sendDvwMessageBoby*/
System.out.println("发送水准数据包");
ByteConvert.printHexString(sendSqvMessageBody);
outputStream.write(sendSqvMessageBody);
//刷新缓冲
outputStream.flush();
outputStream.close();
socket.close();
state =2;
count = 0;
}
else if(state == 2){
System.out.println("数据包回复");
inputStream.read(bytes1);
String hexStr1 = ByteArrayToHexStr(bytes);
info += HexStrToStr(hexStr1);
ByteConvert.printHexString(bytes1);
}
}
/*count ++;
if(count > 5 && sendSqvMessageBody!=null)
{
//sendSqvMessageBody = sendSqvMessageBody(number, 5.23);
System.out.println("发送水准数据包");
ByteConvert.printHexString(sendSqvMessageBody);
outputStream.write(sendSqvMessageBody);
//刷新缓冲
outputStream.flush();
count = 0;
}*/
System.out.println(count);
}
}
catch (IOException e)
{
e.printStackTrace();
}
byte[] str ={0x30,0x7E,0x08,0x7D,0x55};
}
/**
* CRC校验后返回
* @param value
* @return
*/
public static byte[] uint16ToBytes(int value)
{
byte[] src = new byte[2];
src[0] = (byte) ((value>>8) & 0xFF);
src[1] = (byte) (value & 0xFF);
return src;
}
static int i=5;
public static int getDowDateNum(String number){
/*Date now = new Date();*/
i++;
/*SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd ");//设置日期格式
String str = df.format(new Date());*/
//System.out.println(str);
if(numberMap.isEmpty()){
numberMap.put(number, i);
}else{
numberMap.put(number, i);
}
return numberMap.get(number);
}
public static String getIP() {
String ip = "http://pv.sohu.com/cityjson?ie=utf-8";
String inputLine = "";
String read = "";
String toIp="";
try {
URL url = new URL(ip);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
while ((read = in.readLine()) != null) {
inputLine += read;
}
String ObjJson=inputLine.substring(inputLine.indexOf("=")+1,inputLine.length()-1);
JSONObject jsonObj= JSON.parseObject(ObjJson);
toIp=jsonObj.getString("cip");
} catch (Exception e) {
toIp="";
}
return toIp;
}
public static byte[] check7EGetNewArray(byte[] mBaseData) {
int length =0;
for(int i = 0; i<mBaseData.length;i++){
if(mBaseData[i]==0x7E){
length = length+2;
}else{
length = length+1;
}
}
byte[] src = new byte[length];
int j=0;
for(int i = 0; i<mBaseData.length;i++){
if(mBaseData[i]==0x7E){
src[j]=0x7D;
src[j+1]=0x02;
j=j+2;
}else{
src[j]=mBaseData[i];
j++;
}
}
return src;
}
public static byte[] check7DGetNewArray(byte[] mBaseData) {
int length =0;
for(int i = 0; i<mBaseData.length;i++){
if(mBaseData[i]==0x7D){
length = length+2;
}else{
length = length+1;
}
}
byte[] src = new byte[length];
int j=0;
for(int i = 0; i<mBaseData.length;i++){
if(mBaseData[i]==0x7D){
src[j]=0x7D;
src[j+1]=0x01;
j=j+2;
}else{
src[j]=mBaseData[i];
j++;
}
}
return src;
}
/**
*
* @param data1
* @param data2
* @return data1 与 data2拼接的结果
*/
public static byte[] addBytes(byte[] data1, byte[] data2) {
byte[] data3 = new byte[data1.length + data2.length];
System.arraycopy(data1, 0, data3, 0, data1.length);
System.arraycopy(data2, 0, data3, data1.length, data2.length);
return data3;
}
public static byte[] addAllBytes(byte[] data1, byte[] data2,byte[] data3) {
byte[] data4 = new byte[data1.length + data2.length + data3.length];
System.arraycopy(data1, 0, data4, 0, data1.length);
System.arraycopy(data2, 0, data4, data1.length, data2.length);
System.arraycopy(data3, 0, data4, data1.length+data2.length, data3.length);
return data4;
}
public static String ByteArrayToHexStr(byte[] byteArray)
{
if (byteArray == null)
{
return null;
}
char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[byteArray.length * 2];
for (int i = 0; i < byteArray.length; i++)
{
int temp = byteArray[i] & 0xFF;
hexChars[i * 2] = hexArray[temp >>> 4];
hexChars[i * 2 + 1] = hexArray[temp & 0x0F];
}
return new String(hexChars);
}
/**
* 16进制的Str转Str
*
* @param hexStr
* @return
*/
public static String HexStrToStr(String hexStr)
{
//能被16整除,肯定可以被2整除
byte[] array = new byte[hexStr.length() / 2];
try
{
for (int i = 0; i < array.length; i++)
{
array[i] = (byte) (0xff & Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16));
}
hexStr = new String(array, "UTF-8");
}
catch (Exception e)
{
e.printStackTrace();
return "";
}
return hexStr;
}
public static void sendData(int flag,String number,double data) throws Exception{
byte[] messageHeader = getMessageHeader(0, number);//消息头
byte[] endAllBytes =getRegistrationPackageAllMessage(messageHeader, 0, number);
/*byte[] endAllBytes = sendHeartbeatPacketMessageBody(2, number);//心跳包
* */
/*byte[] endAllBytes =getAuthenticationPacketMessageBody(1, number);//鉴权包
*/ OutputStream outputStream = null;
Socket socket = null;
try
{
socket = new Socket("xxxx", xxx);
//得到一个输出流,用于向服务器发送数据
outputStream = socket.getOutputStream();
outputStream.write(endAllBytes);
//刷新缓冲
outputStream.flush();
//得到一个输入流,用于接收服务器响应的数据
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1]; // 一次读取一个byte
byte[] bytes1 = new byte[103]; //
String info = "";
byte[] keyToken=new byte[32];//鉴权码
int state = 0;
int count = 0;
byte[] sendSqvMessageBody=null;
while (true)
{
if (inputStream.available() > 0)
{
if(state == 0)
{
inputStream.read(bytes1);
String hexStr = ByteArrayToHexStr(bytes);
info += HexStrToStr(hexStr);
//已经读完
if (inputStream.available() == 0)
{
if(bytes1[1]==0x01){
System.arraycopy(bytes1,2 , keyToken , 0, 32);
}
byte[] authenticationPacketMessageBody = getAuthenticationPacketMessageBody(keyToken, 1, number);
outputStream.write(authenticationPacketMessageBody);
//刷新缓冲
outputStream.flush();
state =1;
}
}
else if(state == 1)
{
//System.out.println("鉴权包回复");
inputStream.read(bytes1);
String hexStr1 = ByteArrayToHexStr(bytes);
info += HexStrToStr(hexStr1);
//ByteConvert.printHexString(bytes1);
if(flag == 2){
sendSqvMessageBody = sendDvwMessageBoby(number, data);//应变
}else{
sendSqvMessageBody = sendSqvMessageBody(number, data);//水准仪
}
outputStream.write(sendSqvMessageBody);
//刷新缓冲
outputStream.flush();
state =2;
count = 0;
outputStream.close();
socket.close();
}
else if(state == 2){
/*System.out.println("数据包回复");
inputStream.read(bytes1);
String hexStr1 = ByteArrayToHexStr(bytes);
info += HexStrToStr(hexStr1);
ByteConvert.printHexString(bytes1);*/
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
outputStream.close();
socket.close();
}
}
}
package TCPserver;
public class CRC16 {
static byte[] crc16_tab_h = { (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40 };
static byte[] crc16_tab_l = { (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12,
(byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4, (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7,
(byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68, (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74,
(byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D,
(byte) 0x4C, (byte) 0x8C, (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40 };
/**
* 计算CRC16校验
*
* @param data
* 需要计算的数组
* @return CRC16校验值
*/
public static int calcCrc16(byte[] data) {
return calcCrc16(data, 0, data.length);
}
/**
* 计算CRC16校验
*
* @param data
* 需要计算的数组
* @param offset
* 起始位置
* @param len
* 长度
* @return CRC16校验值
*/
public static int calcCrc16(byte[] data, int offset, int len) {
return calcCrc16(data, offset, len, 0xffff);
}
/**
* 计算CRC16校验
*
* @param data
* 需要计算的数组
* @param offset
* 起始位置
* @param len
* 长度
* @param preval
* 之前的校验值
* @return CRC16校验值
*/
public static int calcCrc16(byte[] data, int offset, int len, int preval) {
int ucCRCHi = (preval & 0xff00) >> 8;
int ucCRCLo = preval & 0x00ff;
int iIndex;
for (int i = 0; i < len; ++i) {
iIndex = (ucCRCLo ^ data[offset + i]) & 0x00ff;
ucCRCLo = ucCRCHi ^ crc16_tab_h[iIndex];
ucCRCHi = crc16_tab_l[iIndex];
}
return ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff;
}
}
package com.AIOT.utils;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import javax.crypto.Cipher;
impo