mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-04-20 19:15:35 +08:00
91 lines
3.0 KiB
Java
91 lines
3.0 KiB
Java
package com.jsowell.common;
|
||
|
||
import com.jsowell.common.util.BytesUtil;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
|
||
import java.util.Arrays;
|
||
|
||
/**
|
||
* 友电电单车充电桩协议工具类
|
||
*/
|
||
@Slf4j
|
||
public class YouDianUtils {
|
||
|
||
|
||
/**
|
||
* 将byte数组转换为物理ID
|
||
* @param bytes 输入的byte数组
|
||
* @return 物理ID对象,包含设备识别码和二维码下方的编号
|
||
*/
|
||
public static int convertToPhysicalId(byte[] bytes) {
|
||
// 检查输入是否合法
|
||
if (bytes == null || bytes.length != 4) {
|
||
throw new IllegalArgumentException("Input byte array must be of length 4.");
|
||
}
|
||
|
||
// 小端模式转大端模式
|
||
byte[] bigEndianBytes = new byte[4];
|
||
bigEndianBytes[0] = bytes[3];
|
||
bigEndianBytes[1] = bytes[2];
|
||
bigEndianBytes[2] = bytes[1];
|
||
bigEndianBytes[3] = bytes[0];
|
||
|
||
// 提取设备识别码
|
||
byte deviceId = bigEndianBytes[0];
|
||
|
||
// 剩余的三个字节转换为十进制
|
||
int deviceNumber = ((bigEndianBytes[1] & 0xFF) << 16) |
|
||
((bigEndianBytes[2] & 0xFF) << 8) |
|
||
(bigEndianBytes[3] & 0xFF);
|
||
log.debug("设备识别码:{}, 桩编号:{}", deviceId, deviceNumber);
|
||
return deviceNumber;
|
||
}
|
||
|
||
/**
|
||
* 校验方法
|
||
* 整个数据包中的每个字节(不包括校验字段本身),将它们的数值累加起来。然后取累加和的低2字节(16位),作为校验字段的值
|
||
* @param bytes 完整数据包, 包含校验字段
|
||
*/
|
||
public static boolean validateChecksum(byte[] bytes) {
|
||
if (bytes.length < 2) {
|
||
return false; // 校验字段长度不足时返回 false
|
||
}
|
||
|
||
byte[] copyOfRange = Arrays.copyOfRange(bytes, 0, bytes.length - 2);
|
||
int calculatedChecksum = calculateCheckField(copyOfRange);
|
||
|
||
// 读取校验字段的值
|
||
byte[] checksumBytes = {bytes[bytes.length - 2], bytes[bytes.length - 1]};
|
||
int receivedChecksum = BytesUtil.bytesToIntLittle(checksumBytes);
|
||
|
||
// 比较计算的校验值和接收到的校验值
|
||
log.info("计算的校验值:{}, 接收到的校验值:{}", calculatedChecksum, receivedChecksum);
|
||
return calculatedChecksum == receivedChecksum;
|
||
}
|
||
|
||
/**
|
||
* 计算校验字段
|
||
* @param bytes 数据包不含校验字段, 包头+长度+物理ID+消息ID+命令+数据
|
||
*/
|
||
public static int calculateCheckField(byte[] bytes) {
|
||
// 计算累加和
|
||
int sum = 0;
|
||
for (byte aByte : bytes) {
|
||
sum += (aByte & 0xFF); // 将每个字节视为无符号值进行累加
|
||
}
|
||
|
||
// 取累加和的低 2 字节(16 位)
|
||
int i = sum & 0xFFFF;
|
||
// log.info("计算校验字段:{}", i);
|
||
return i;
|
||
}
|
||
|
||
/**
|
||
* 获取校验字段byte数组 小端
|
||
*/
|
||
public static byte[] getCheckFieldBytes(byte[] bytes) {
|
||
int calculatedChecksum = calculateCheckField(bytes);
|
||
return BytesUtil.intToBytesLittle(calculatedChecksum);
|
||
}
|
||
}
|