package com.jsowell.common; import com.jsowell.common.util.BytesUtil; import lombok.extern.slf4j.Slf4j; import java.util.Arrays; /** * 友电电单车充电桩协议工具类 */ @Slf4j public class YouDianUtils { public static void main(String[] args) { String s = "44 4e 59 0a 00 3b 37 ab 04 01 00 21 00 38 02"; byte[] bytes = BytesUtil.hexStringToByteArray(s); String s2 = BytesUtil.printHexBinary(bytes); System.out.println(s2); byte[] bytes2 = BytesUtil.hexStringToByteArray(s2); System.out.println(bytes2); boolean b = validateChecksum(bytes); // String s3 = "44 4e 59 0a 00 3b 37 ab 04 01 00 21 00"; byte[] bytes3 = BytesUtil.hexStringToByteArray(s3); int i = calculateCheckField(bytes3); BytesUtil.intToBytesLittle(i); } /** * 校验方法 * 整个数据包中的每个字节(不包括校验字段本身),将它们的数值累加起来。然后取累加和的低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); } }