帧结构(报文结构)

请添加图片描述


示例:681A68B35303810D00C00059000000826110000001106000004508090A3516

  1. 681A68:开始字符串 字符串长度 开始字符串

  2. B3为控制域(数据类型)

    1)0000B—雨量;

  1. 0001B—水位;
  2. 0010B—流量(水量);
  3. 0011B—流速;
  4. 0100B—闸位;
  5. 0101B—功率;
  6. 0110B—气压;
  7. 0111B—风速(风向);
  8. 1000B—水温;
  9. 1001B—水质;
  10. 1010B—土壤含水率;
  11. 1011B—水压;
  12. 1100B—1111B 备用。
  1. 5303810D00为地址域(测站地址) 22 24 06为行政区代码 07 00测站地址
  2. 0059000000826110000001106000004508090A 用户数据(报文正文)
  3. 35: 校验CS
  4. 16: 结束字符(固定)


用户数据域解析(正文解析)

正文需要从后面开始解析

正文:0059000000826110000001106000004508090A

  1. 后10位为时间 :004508090A //00(秒-十位个位)45(分-十位个位)08(时-十位个位)09(日-十位个位),解析后为09日 08:45:00 年月需要自己补充。

  2. 再往前8位 01106000为报警值 转换为2进制 00000001000100000000011000000000 (每位转成4位2进制数不足补0)

    前16位数
    请添加图片描述

    后16位数

    请添加图片描述


  3. 剩余的为相关数据 00590000008261100000

    由于数据类型为 B3 0010B—流量(水量)

    按照文档6.2.26解析各种类型的数据

请添加图片描述



传输规约是5个字节代表一个数据,00 59 00 00 00 为流量数据,82 61 10 00 00 为水量数据

再按照每个位置代表的 数字位数解析后

流量为 00 00 00 59 00 实际数据为5.9 m3/s
水量 00 00 10 61 82 实际为106182 m3/h

请添加图片描述

java代码




/**
 * @author CaoLongMin
 * @version 1.0
 * @description TODO
 * @since 2022/6/20
 */
@Slf4j
@Service
public class Szy206Parser extends BaseParser {
    @Autowired
    private LotDeviceMapper lotDeviceMapper;
    @Autowired
    private ParserService parserService;

    @Autowired
    private RedisTemplate redisTemplate;
    private final String SZY_REDIS_KEY="device:data:szy:";
    @Override
    public UrlDTO getUrlInfo(String interfaceId, String deviceId) {
        return null;
    }

    @Override
    public Map<String, Object> dataParser(String msg, String deviceId) {
        Szy206InfoDTO szy206InfoDTO=new Szy206InfoDTO();
        //示例 681A68B35303810D00C00059000000826110000001106000004508090A3516
        szy206InfoDTO.setContent(msg);
        //681A68开始字符串 字符串长度 开始字符串
        Integer index=0;
        //开始字符串
        String startStr=msg.substring(index,index+6);
        szy206InfoDTO.setStartStr(startStr);
        index+=6;


        //B3为数据类型(流量(水量))
        //1) 0000B—雨量;
        //2) 0001B—水位;
        //3) 0010B—流量(水量);
        //4) 0011B—流速;
        //5) 0100B—闸位;
        //6) 0101B—功率;
        //7) 0110B—气压;
        //8) 0111B—风速(风向);
        //9) 1000B—水温;
        //10) 1001B—水质;
        //11) 1010B—土壤含水率;
        //12) 1011B—水压;
        //13) 1100B—1111B 备用。

        //数据类型
        String dataType=msg.substring(index,index+2);
        szy206InfoDTO.setDataType(dataType);
        index+=2;

        //5303810D00为测站地址  530381为行政区代码  0D00测站地址
        //遥测地址
        String stationAddr=msg.substring(index,index+10);
        szy206InfoDTO.setStationAddr(stationAddr);
        szy206InfoDTO.setDeviceId(dataType+stationAddr);
        index+=10;
        //C0   C0H遥测终端自报实时数据 遥测终端 中心站
        //应用层功能码
        String functionCode=msg.substring(index,index+2);
        szy206InfoDTO.setFunctionCode(functionCode);
        index+=2;
        //0059000000826110000001106000004508090A  报文正文
        //正文
        String content=msg.substring(index,msg.length()-4);

        index=msg.length()-4;
        //35 crc校验
        //crc校验码
        String crcCode=msg.substring(index,index+2);
        szy206InfoDTO.setCrcCode(crcCode);
        index+=2;
        //16 结束字符(固定)
        //结束字符串16
        String endStr=msg.substring(index,index+2);
        szy206InfoDTO.setEndStr(endStr);

        parseContent(content,szy206InfoDTO);
        Map<String,Object> map= (Map<String, Object>) JSONUtil.parse(szy206InfoDTO);
        return map;

    }

    private void parseContent(String content, Szy206InfoDTO szy206InfoDTO) {
        szy206InfoDTO.setIsHeartbeat(false);
        if(content.length()<3||szy206InfoDTO.getFunctionCode().equals("02")){
            szy206InfoDTO.setIsHeartbeat(true);
            log.info("心跳检测数据");
        }else{
            Map<String,Object> mainBody=new HashMap<>();
            Map<String,Object> mainHead=new HashMap<>();
            //倒着解析
            int index=content.length();
            String deviceIndex="";
            //C0是RTU自报数据  B0是平台查询
            if(szy206InfoDTO.getFunctionCode().equals("C0")&&index>18) {
                //004508090A
                //00(秒-十位个位)45(分-十位个位)08(时-十位个位)09(日-十位个位),解析后为09日 08:45:00 年月需要自己补充。
                String time = content.substring(index - 10, index);
                Integer year = DateTime.now().year();
                Integer month = DateTime.now().monthBaseOne();
                Integer day = Integer.parseInt(time.substring(6, 8));
                Integer hour = Integer.parseInt(time.substring(4, 6));
                Integer minutes = Integer.parseInt(time.substring(2, 4));
                Integer seconds = Integer.parseInt(time.substring(0, 2));
                String dateTimeStr = year + "/" + month + "/" + day + " " + hour + ":" + minutes + ":" + seconds;
                DateTime dateTime = DateUtil.parseDateTime(dateTimeStr);
                String timeStr = dateTime.toString();
                szy206InfoDTO.setDataTime(timeStr);

                mainBody.put(DataInfoConstant.DATA_TIME, timeStr);
                mainHead.put(DataInfoConstant.DATA_TIME, DataInfoConstant.DATA_TIME_MEAN);
                index -= 10;
            }
            String warningStatus=content.substring(index-8,index);
            //暂时只解析电压状态
            char[] binArr=warningStatus.toCharArray();
            String warningStr="";
            for(char ch:binArr){
                String ss=String.valueOf(ch);
                warningStr+=MathUtil.hexString2binaryString(ss);
            }
            //第二位为电压报警状态 0为不报警 1为报警
            String voltageStr;
            if(warningStr.substring(1,2).equals("0")){
                voltageStr="正常";
            }else{
                voltageStr="报警";
            }
            mainBody.put(Szy206TypeEnum.VOLTAGE.getKey(),voltageStr);
            mainHead.put(Szy206TypeEnum.VOLTAGE.getKey(),Szy206TypeEnum.VOLTAGE.getDescription());
            index-=8;
            String dataContent=content.substring(0,index);
            if(Szy206TypeEnum.RAINFALL.getKey().equals(szy206InfoDTO.getDataType())){
                //降雨量
                deviceIndex=Szy206TypeEnum.RAINFALL.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=6;
                //小数点位数
                int decimalPoint=5;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else if(Szy206TypeEnum.WATER_LEVEL.getKey().equals(szy206InfoDTO.getDataType())){
                //水位
                deviceIndex=Szy206TypeEnum.WATER_LEVEL.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=8;
                //小数点位数
                int decimalPoint=5;

                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,true,mainBody,mainHead);
            }else if(Szy206TypeEnum.TRAFFIC.getKey().equals(szy206InfoDTO.getDataType())){
                //流量
                deviceIndex=Szy206TypeEnum.TRAFFIC.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=10;
                //小数点位数
                int decimalPoint=7;
                int dataLength=dataContent.length();
                if(dataLength%oneDataLength==0) {
                    int cycleNum = 0;
                    int flag=2;
                    while (dataLength > 0) {
                        try {
                            String data = dataContent.substring(cycleNum * oneDataLength, (cycleNum + 1) * oneDataLength);
                            cycleNum++;
                            dataLength -= oneDataLength;
                            char[] dataChar = data.toCharArray();
                            String result;
                            //实时流量在前 累计流量在后
                            if(flag%2==0){
                                //流量实时数据
                                result = char2String(dataChar, decimalPoint,true);
                                Double resultData=Double.parseDouble(result);
                                mainBody.put("flow",resultData);
                                mainHead.put("flow","流量");
                                log.info("遥测地址:"+szy206InfoDTO.getStationAddr()+" 类型:流量"+" 结果:"+resultData);
                            }else{
                                //累计流量(水量)
                                result = char2String(dataChar, 0,true);
                                Double resultData=Double.parseDouble(result);
                                mainBody.put("countFlow",resultData);
                                mainHead.put("countFlow","累计流量");
                                log.info("遥测地址:"+szy206InfoDTO.getStationAddr()+" 类型:累计流量"+" 结果:"+resultData);
                            }
                            flag++;


                        } catch (Exception e) {
                            System.out.println(e.toString());
                        }
                    }
                }
            }else if(Szy206TypeEnum.VELOCITY.getKey().equals(szy206InfoDTO.getDataType())){
                //流速
                deviceIndex=Szy206TypeEnum.VELOCITY.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=6;
                //小数点位数
                int decimalPoint=3;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,true,mainBody,mainHead);
            }else if(Szy206TypeEnum.GATES.getKey().equals(szy206InfoDTO.getDataType())){
                //闸位
                deviceIndex=Szy206TypeEnum.GATES.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=6;
                //小数点位数
                int decimalPoint=4;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else if(Szy206TypeEnum.POWER.getKey().equals(szy206InfoDTO.getDataType())){
                //功率
                deviceIndex=Szy206TypeEnum.POWER.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=6;
                //小数点位数
                int decimalPoint=0;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else if(Szy206TypeEnum.AIR_PRESSURE.getKey().equals(szy206InfoDTO.getDataType())){
                //气压
                deviceIndex=Szy206TypeEnum.AIR_PRESSURE.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=6;
                //小数点位数
                int decimalPoint=0;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else if(Szy206TypeEnum.WIND_SPEED.getKey().equals(szy206InfoDTO.getDataType())){
                //风速
                deviceIndex=Szy206TypeEnum.WIND_SPEED.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=6;
                //小数点位数
                int decimalPoint=4;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else if(Szy206TypeEnum.WATER_TEMPERATURE.getKey().equals(szy206InfoDTO.getDataType())){
                //水温
                deviceIndex=Szy206TypeEnum.WATER_TEMPERATURE.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=4;
                //小数点位数
                int decimalPoint=3;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else if(Szy206TypeEnum.MOISTURE_CONTENT.getKey().equals(szy206InfoDTO.getDataType())){
                //土壤含水率
                deviceIndex=Szy206TypeEnum.MOISTURE_CONTENT.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=4;
                //小数点位数
                int decimalPoint=4;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else if(Szy206TypeEnum.WATER_PRESSURE.getKey().equals(szy206InfoDTO.getDataType())){
                //水压
                deviceIndex=Szy206TypeEnum.WATER_PRESSURE.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=8;
                //小数点位数
                int decimalPoint=6;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else if(Szy206TypeEnum.WATER_QUALITY.getKey().equals(szy206InfoDTO.getDataType())){
                //水质
                deviceIndex=Szy206TypeEnum.WATER_QUALITY.getDeviceIndex();
                //每N个数组 代表一个数据
                int oneDataLength=8;
                //前十位是检测种类
                String typeStr=dataContent.substring(0,10);
                //每位转成4位二进制数 前面补0
                char[] typeChar=typeStr.toCharArray();
                String binStr="";
                for(char ch:typeChar){
                    binStr+=MathUtil.hexString2binaryString(String.valueOf(ch));
                }
                //根据2进制字符串判断 存在哪些水质参数 1代表存在。
                char[] binaryTypeChar=binStr.toCharArray();
                //存在粪大肠菌群的话 每5个字符代表一个数值 否则4个   (5+N*4(+1【参数含粪大肠菌群时】)+4 个字节。)
                if(String.valueOf(binaryTypeChar[24]).equals("1")){
                    oneDataLength=10;
                }
                List<Integer> indexList=new ArrayList<>();
                //记录1的位置
                for(int i=0;i<binaryTypeChar.length;i++){
                    if(new StringBuilder(binaryTypeChar[i]).toString().equals("1")){
                        indexList.add(i);
                    }
                }

                //获取所有数据list
                int dataLength=dataContent.length();
                List<String> dataList=new ArrayList<>();
                if(dataLength%oneDataLength==0) {
                    int cycleNum=0;
                    while (dataLength > 0) {
                        String data = dataContent.substring(cycleNum * oneDataLength, (cycleNum + 1) * oneDataLength);
                        dataList.add(data);
                    }
                }

                if(indexList.size()==dataList.size()){
                    for(int i=0;i<indexList.size();i++){
                        Szy206WaterQualityEnum szy206WaterQualityEnum =getQualityEnumByKey("D"+indexList.get(i));
                        if(ObjectUtil.isNotEmpty(szy206WaterQualityEnum)){
                            //N(3,1) oneDataLength-3+(3-1)  ==oneDataLength-1; 00000123 小数位数为7
                            Integer decimalPoint=oneDataLength-Integer.parseInt(szy206WaterQualityEnum.getPrecision().split(",")[1].replace(")",""));
                            //TODO不确定是直接将数字倒序就行还是 以下方式(待验证)
                            Double value=Double.parseDouble(char2String(dataList.get(i).toCharArray(),decimalPoint,false));
                            String key=szy206WaterQualityEnum.getKey();
                            log.info("遥测地址:"+szy206InfoDTO.getStationAddr()+"类型:"+szy206WaterQualityEnum.getName()+"结果:"+value);
                            mainBody.put(key,value);
                            mainHead.put(key,szy206WaterQualityEnum.getName()+"("+szy206WaterQualityEnum.getUnit()+")");
                        }
                    }
                }
            }else if(Szy206TypeEnum.OTHERS.getKey().equals(szy206InfoDTO.getDataType())){
                //电压
                deviceIndex=Szy206TypeEnum.OTHERS.getDeviceIndex();
                //每N个数字 代表一个数据
                int oneDataLength=4;
                //小数点位数 第N个数组后
                int decimalPoint=2;
                parentDataInfo(szy206InfoDTO,dataContent,oneDataLength,decimalPoint,false,mainBody,mainHead);
            }else{
                log.warn("数据类型未匹配:"+szy206InfoDTO.getDataType()+"报文为:"+szy206InfoDTO.getContent());
            }


            szy206InfoDTO.setDeviceIndex(deviceIndex);
            szy206InfoDTO.setMainBody(mainBody);
            szy206InfoDTO.setMainHead(mainHead);
        }

    }

    public Szy206WaterQualityEnum getQualityEnumByKey(String key){
        for(Szy206WaterQualityEnum e:Szy206WaterQualityEnum.values()){
            if(e.getKey().equals(key)){
                return e;
            }
        }
        return null;
    }

    /**
     * 解析正文
     * @param szy206InfoDTO 解析实体
     * @param dataContent 正文
     * @param oneDataLength 一个数据长度
     * @param decimalPoint 小数位数
     * @param isNegative 是否判断正方
     * @param mainBody 数据
     * @param mainHead 头部
     */
    public void parentDataInfo( Szy206InfoDTO szy206InfoDTO,String dataContent,Integer oneDataLength, int decimalPoint,Boolean isNegative,Map<String,Object> mainBody,Map<String,Object> mainHead){

        int dataLength=dataContent.length();
        if(dataLength%oneDataLength==0){
            int cycleNum=0;
            while (dataLength>0){
                try{
                    String data=dataContent.substring(cycleNum*oneDataLength,(cycleNum+1)*oneDataLength);
                    cycleNum++;
                    dataLength-=oneDataLength;
                    char[] dataChar=data.toCharArray();
                    String result=char2String(dataChar,decimalPoint,isNegative);
                    Szy206TypeEnum szy206TypeEnum=getTypeEnum(szy206InfoDTO.getDataType());
                    //数据值
                    Double resultData=Double.parseDouble(result);
                    mainBody.put(szy206TypeEnum.getKey(),resultData);
                    mainHead.put(szy206TypeEnum.getKey(),szy206TypeEnum.getDescription());

                    log.info("遥测地址:"+szy206InfoDTO.getStationAddr()+" 类型:"+szy206TypeEnum.getDescription()+" 结果:"+result);
                }catch (Exception e){
                    System.out.println(e.toString());
                }
            }

        }
    }

    public Szy206TypeEnum getTypeEnum(String typeKey){
        for(Szy206TypeEnum szy206TypeEnum:Szy206TypeEnum.values()){
            if(szy206TypeEnum.getKey().equals(typeKey)){
                return szy206TypeEnum;
            }
        }
        return null;
    }
    @Override
    public void insertData(String deviceId, String data) {
        //判断device表中是否有数据

        LambdaQueryWrapper<LotDevicePO> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LotDevicePO::getDeviceId,deviceId);
        List<LotDevicePO> poList= lotDeviceMapper.selectList(lambdaQueryWrapper);
        if(ObjectUtil.isEmpty(poList)){
            JSONObject map= JSONUtil.parseObj(data);
            LotDevicePO lotDevicePO=new LotDevicePO();
            lotDevicePO.setDeviceId(deviceId);
            lotDevicePO.setIsAdd(0);
            //离线判断时间默认10分钟
            lotDevicePO.setOfflineTime(10);
            lotDevicePO.setDeviceType(FieldConstan.DEVICE_TYPE_SELF_BUILT);
            lotDevicePO.setOnlineTime(DateTime.now());
            lotDevicePO.setOnlineStatus(1);
            if(ObjectUtil.isNotEmpty(map.get(DataInfoConstant.DEVICE_INDEX))){
                lotDevicePO.setDeviceIndex(map.get(DataInfoConstant.DEVICE_INDEX).toString());
            }
            lotDevicePO.setProtocol("SZY206");
            lotDeviceMapper.insert(lotDevicePO);
        }
        parserService.insertData(deviceId,data);
    }

    @Override
    public void isOnline(String deviceId, Map<String, Object> msg) {
        //修改状态采集时间
        LambdaQueryWrapper<LotDevicePO> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LotDevicePO::getDeviceId,deviceId);
        List<LotDevicePO> poList= lotDeviceMapper.selectList(lambdaQueryWrapper);
        if(ObjectUtil.isNotEmpty(poList)&&poList.size()>0){
            LotDevicePO lotSensorPO=poList.get(0);
            lotSensorPO.setOnlineTime(DateTime.now());
            lotSensorPO.setOnlineStatus(1);
            lotDeviceMapper.update(lotSensorPO,lambdaQueryWrapper);
        }
    }

    public void addVoltageData(Szy206InfoDTO szy206InfoDTO){
        if(ObjectUtil.isNotEmpty(szy206InfoDTO.getMainBody().get("BD"))){
            String dy=szy206InfoDTO.getMainBody().get("BD").toString();
            log.info(szy206InfoDTO.getStationAddr()+"电压数据为"+szy206InfoDTO.getMainBody().get("BD"));
            //将电压数据拼接到 原数据中
            //查询出原数据
            // *号 必须要加,否则无法模糊查询
            String prefix = SZY_REDIS_KEY+szy206InfoDTO.getStationAddr()+"*";
            // 获取所有addr相同的数据
            Set<String> keys = redisTemplate.keys(prefix);
            List<Object> myObjectListRedis = redisTemplate.opsForValue().multiGet(keys);
            if(ObjectUtil.isNotEmpty(myObjectListRedis)&&myObjectListRedis.size()>0){
                for(Object o:myObjectListRedis){
                    Szy206InfoDTO redisDto= BeanUtil.toBean(o,Szy206InfoDTO.class);
                    if(ObjectUtil.isNotEmpty(redisDto.getMainHead())&&ObjectUtil.isNotEmpty(redisDto.getMainBody())){
                        redisDto.getMainBody().put("BD",dy);
                        redisDto.getMainHead().put("BD","电压(v)");
                        //插入数据
                        insertData(redisDto.getDeviceId(),JSONUtil.toJsonStr(redisDto));
                        isOnline(redisDto.getDeviceId(),(Map<String, Object>) JSONUtil.parse(redisDto));
                    }

                }
                //删除redis
                redisTemplate.delete(keys);
            }

        }

    }

    public void saveDataToRedis(Szy206InfoDTO szy206InfoDTO) {
        String key=SZY_REDIS_KEY+szy206InfoDTO.getStationAddr()+ IdUtil.fastUUID();
        redisTemplate.opsForValue().set(key,szy206InfoDTO);
    }


    public String char2String(char[] ch,Integer decimalPoint,Boolean isNegative){
        //将char 2位分为一组 并倒序排列(低位在前高位在后)
        int length=ch.length/2;
        String[] dataArray=new String[length];
        for(int i=0;i<ch.length;i+=2){
            String c=ch[i]+""+ch[i+1];
            dataArray[length-1]=c;
            length--;
        }


        StringBuilder stringBuilder=new StringBuilder();

        for(int j=0;j<dataArray.length;j++){
            if(j==0){
                if(isNegative){
                    //第一位代表+ -值
                    if(Integer.parseInt(dataArray[j].substring(0,1))!=0){
                        stringBuilder.append("-");
                    }else{
                        stringBuilder.append("+");
                    }
                    stringBuilder.append(dataArray[j].substring(1,2));
                }else{
                    stringBuilder.append(dataArray[j]);
                }

            }else{
                stringBuilder.append(dataArray[j]);
            }
        }
        String resultDataStr=stringBuilder.toString();
        //添加小数点
        if(decimalPoint!=0){
            resultDataStr=stringBuilder.toString().substring(0,decimalPoint)+"."+stringBuilder.toString().substring(decimalPoint,stringBuilder.length());
        }

        return resultDataStr;
    }



    //
}





	/**
     * 多项式 X^7+X^6+X^5+X^2+1  (0xE5)
     * @param str
     * @return
     */
    public static String calcCrc8(String str) {
        byte[] data = HexUtil.decodeHex(str);
        int crc = 0x00;
        int dxs = 0xE5;
        int hibyte;
        int sbit;
        for (byte datum : data) {
            crc = crc ^ datum;
            for (int j = 0; j < 8; j++) {
                sbit = crc & 0x80;
                crc = crc << 1;
                if (sbit != 0) {
                    crc ^= dxs;
                }

            }
        }
        String code = Integer.toHexString(crc & 0xff).toUpperCase();
        return code;
    }
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐