NtripShare Cloud平台之CORS服务之基准站RTCM坐标编辑

news2024/10/24 6:24:36

最近有点累,一直在摸鱼,想在平差方面做点事情,但是一直在构思应该怎么去做,有想法的朋友可以交流。

收到了TW和国内顶尖测绘行业朋友的需求:

1、将NtripShare Cloud的CORS服务模块由单基站模块改为VRS。

2、由于电离层影响,基于VRS的CORS服务出现大面积的不能固定,需要使用单基站的网络CORS服务,但是由于CORS站本身的特殊性,不能对外暴扣精确的基准站坐标,能否在CORS软件中将单基站播发的RTCM中的基准站坐标进行编辑修改(测量结果需要后处理)。

其中VRS这件事有很多朋友提过,一直以来也没有做,主要考虑一下三点:

1、友商的VRS产品很多,没有必要再去做一款,已经很卷了。

2、VRS需要一定的技术难度,可以查找到的资料非常少。

3、NtripShare Cloud的CORS模块采用的是Java的技术路线,在应对大并发方面有一定优势,但是对于RTCM这种实时数据流解析与计算不是很适用。

RTCM基准站坐标编辑修改这事评估了一下可行,耗费四天时间,实现了在Java端的RTCM数据解析与1005、1006报文的实时修正。不得不说关于GNSS方面的java开源项目实在是太少了,真的只能手撸。这次的代码开放一部分,以便大家少走弯路。


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class Rtcm1005 extends RtcmMessage {

    private static Logger logger = LoggerFactory.getLogger(Rtcm1005.class);
    public double[] ecef = new double[3];
    public double[] lla = new double[3];

    public Rtcm1005(byte[] data, int index, int length) {
        super(data, index, length);
    }

    public Rtcm1005() {
        super(new byte[25], 0, 25);
    }

    public void setECEF(double x, double y, double z) {
        ecef[0] = x;
        ecef[1] = y;
        ecef[2] = z;
        lla = GeoCode.ecef2lla(ecef);
    }

    public void setLatLon(double lat, double lon, double alt) {
        lla[0] = lat;
        lla[1] = lon;
        lla[2] = alt;
        ecef = GeoCode.lla2ecef(lla);
    }

    @Override
    public Rtcm1005 decode() {
        int bitPoint = HEADER_BYTE_LENGTH * 8;
        // DF002 Message Number
        messageType = Utilities.bitToInt(data, bitPoint, 12);
        bitPoint += 12;
        // DF003 Reference Station ID
        @SuppressWarnings("unused")
        int stationID = Utilities.bitToInt(data, bitPoint, 12);
        bitPoint += 12;
        // DF021 ITRF (not used)
        bitPoint += 6;
        // DF022/023/024/141
        bitPoint += 4;
        // DF025 Antenna Reference Point ECEF-X
        ecef[0] = Utilities.bitToLongMSB(data, bitPoint, 38) * 0.0001;
        bitPoint += 38;
        // DF142/001
        bitPoint += 2;
        // DF026 Antenna Reference Point ECEF-Y
        ecef[1] = Utilities.bitToLongMSB(data, bitPoint, 38) * 0.0001;
        bitPoint += 38;
        // DF364
        bitPoint += 2;
        // DF027 Antenna Reference Point ECEF-Y
        ecef[2] = Utilities.bitToLongMSB(data, bitPoint, 38) * 0.0001;
//        bitPoint += 38;
        lla = GeoCode.ecef2lla(ecef);

        return this;
    }

    @Override
    public String getSuccinctInfo() {
        return "ECEF\t" + Arrays.toString(ecef) + "\r\nLLA\t" + Arrays.toString(lla);
    }

    @Override
    public String getAnalyzedString() {
        return "Stationary RTK Reference Station ARP\r\n" +
                "ECEF(X) " + ecef[0] + ", ECEF(Y) " + ecef[1] + ", ECEF(Z) " + ecef[2] + "\r\n";
    }

    public byte[] recode() {
        ecef = GeoCode.lla2ecef(lla);
        int i = 24;
//        Utilities.setbitu(datass, i, 12, 1005);
        i += 12; /* message no */
//        Utilities.setbitu(datass, i, 12, 0);
        i += 12; /* ref station id */
//        Utilities.setbitu(datass, i, 6, 0);
        i += 6; /* itrf realization year */
//        Utilities.setbitu(datass, i, 1, 1);
        i += 1; /* gps indicator */
//        Utilities.setbitu(datass, i, 1, 1);
        i += 1; /* glonass indicator */
//        Utilities.setbitu(datass, i, 1, 0);
        i += 1; /* galileo indicator */
//        Utilities.setbitu(datass, i, 1, 0);
        i += 1; /* ref station indicator */
//        logger.info("--"+Utilities.getBinaryStrFromByte2( data,i,38));
        Utilities.longToBitMSB(data, i, ecef[0] / 0.0001);
//        logger.info("AA"+Utilities.getBinaryStrFromByte2( data,i,38));
        i += 38; /* antenna ref point ecef-y */
//        Utilities.setbitu(datass, i, 1, 1);
        i += 1; /* oscillator indicator */
//        Utilities.setbitu(datass, i, 1, 1);
        i += 1; /* reserved */
        Utilities.longToBitMSB(data, i, ecef[1] / 0.0001);
//        logger.info("BB"+Utilities.getBinaryStrFromByte( data));
        i += 38; /* antenna ref point ecef-y */
//        Utilities.setbitu(datass, i, 2, 0);
        i += 2; /* quarter cycle indicator */
        Utilities.longToBitMSB(data, i, ecef[2] / 0.0001);
//        logger.info("CC"+Utilities.getBinaryStrFromByte( data));
        i += 38; /* antenna ref point ecef-z */
        int crc = 0;
        for (int m = 0; m < data.length - DecodeRTCM3.CRCBYTELENGTH; m++) {
            crc ^= data[0 + m] << 16;
            for (int j = 0; j < 8; j++) {
                crc <<= 1;
                if ((crc & 0x1000000) != 0) {
                    crc ^= DecodeRTCM3.CRC24_POLY;
                }
            }
        }
        Utilities.intToBit(data, (data.length - DecodeRTCM3.CRCBYTELENGTH) * 8, DecodeRTCM3.CRCBYTELENGTH * 8, crc);
        return data;
    }

    @Override
    public byte[] encode() {
        ecef = GeoCode.lla2ecef(lla);
        data = Utilities.hexToByteArray("d300133ed00003fab70dd5be0a44a89893094e19c0e5f16d7b");
        int i = 24;
//        Utilities.setbitu(data, i, 12, 1005);
        i += 12; /* message no */
//        Utilities.setbitu(data, i, 12, 0);
        i += 12; /* ref station id */
//        Utilities.setbitu(data, i, 6, 0);
        i += 6; /* itrf realization year */
//        Utilities.setbitu(data, i, 1, 1);
        i += 1; /* gps indicator */
//        Utilities.setbitu(data, i, 1, 1);
        i += 1; /* glonass indicator */
//        Utilities.setbitu(data, i, 1, 0);
        i += 1; /* galileo indicator */
//        Utilities.setbitu(data, i, 1, 0);
        i += 1; /* ref station indicator */
//        logger.info("--"+Utilities.getBinaryStrFromByte2( data,i,38));
        Utilities.longToBitMSB(data, i, ecef[0] / 0.0001);
//        logger.info("AA"+Utilities.getBinaryStrFromByte2( data,i,38));
        i += 38; /* antenna ref point ecef-y */
//        Utilities.setbitu(data, i, 1, 1);
        i += 1; /* oscillator indicator */
//        Utilities.setbitu(data, i, 1, 1);
        i += 1; /* reserved */
        Utilities.longToBitMSB(data, i, ecef[1] / 0.0001);
//        logger.info("BB"+Utilities.getBinaryStrFromByte( data));
        i += 38; /* antenna ref point ecef-y */
//        Utilities.setbitu(data, i, 2, 0);
        i += 2; /* quarter cycle indicator */
        Utilities.longToBitMSB(data, i, ecef[2] / 0.0001);
//        logger.info("CC"+Utilities.getBinaryStrFromByte( data));
        i += 38; /* antenna ref point ecef-z */
        int crc = 0;
        for (int m = 0; m < data.length - DecodeRTCM3.CRCBYTELENGTH; m++) {
            crc ^= data[0 + m] << 16;
            for (int j = 0; j < 8; j++) {
                crc <<= 1;
                if ((crc & 0x1000000) != 0) {
                    crc ^= DecodeRTCM3.CRC24_POLY;
                }
            }
        }
        Utilities.intToBit(data, (data.length - DecodeRTCM3.CRCBYTELENGTH) * 8, DecodeRTCM3.CRCBYTELENGTH * 8, crc);
        return data;
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class RtcmMsm extends RtcmMessage {
    private static final String[] GPSSIGNALMAP = {"","","1C","1P","1W","","","","2C","2P","2W","","","","","2S","2L","2X","","","","","5I","5Q","5X","","","","","","1S","1L","1X"};
    private static final String[] GLONASSSIGNALMAP = {"","","1C","1P","","","","","2C","2P"};
    private static final String[] GALILEOSIGNALMAP = {"","","1C","1A","1B","1X","1Z","","6C","6A","6B","6X","6Z","","7I","7Q","7X","","8I","8Q","8X","","5I","5Q","5X"};
    private static final String[] SBASSINGALMAP = {"","","1C","","","","","","","","","","","","","","","","","","","","5I","5Q","5X"};
    private static final String[] QZSSIGNALMAP = {"","","1C","","","","","","","6S","6L","6X","","","","2S","2L","2X","","","","","5I","5Q","5X","","","","","","1S","1L","1X"};
    private static final String[] BEIDOUSIGNALMAP = {"","","2I","2Q","2X","","","","6I","6Q","6X","","","","7I","7Q","7X"};
    private static final String[][] SIGNALMAP = {GPSSIGNALMAP,GLONASSSIGNALMAP,GALILEOSIGNALMAP,SBASSINGALMAP,QZSSIGNALMAP,BEIDOUSIGNALMAP};

    private int msmType;
    private int gnssType;

    private List<Integer> satelliteList;	
    private List<Integer> signalList;		
    private long cellMask;					
    private int epochTime;
    private List<Integer> ltiList;
    private List<Integer> cnrList;

    public RtcmMsm(byte[] data, int index, int length) {
        super(data, index, length);
    }

    @Override
    RtcmMsm decode() {
        int bitPoint = decodeHeader();
        ltiList = new ArrayList<>();
        cnrList = new ArrayList<>();

        /*
         * satellite Data
         */
        int satelliteNumber = satelliteList.size();
        if(msmType == 4 || msmType == 5 || msmType == 6 || msmType == 7) {
            // DF397	8bits*Nsat
            bitPoint += 8 * satelliteNumber;
        }

        if(msmType == 5 || msmType == 7) {
            // Extended Satellite Information	4bits*Nsat
            bitPoint += 4 * satelliteNumber;
        }

        // DF398	10bits*Nsat
        bitPoint += 10 * satelliteNumber;


        if(msmType == 5 || msmType == 7) {
            // DF399	14bits*Nsat
            bitPoint += 14 * satelliteNumber;
        }

        /*
         * signal Data
         */
        int cellNumber = Long.bitCount(cellMask);
        if(msmType == 1 || msmType == 3 || msmType == 4 || msmType == 5) {
            // DF400 signal fine pseudorange
            bitPoint += 15 * cellNumber;
        }

        if(msmType == 2 || msmType == 3 || msmType == 4 || msmType == 5) {
            // DF401 signal fine phaserange data
            bitPoint += 22 * cellNumber;

            // DF402 phaserange Lock Time Indicator
            for(int i = 0; i < cellNumber; i++) {
                ltiList.add(Utilities.bitToInt(data, bitPoint, 4));
                bitPoint += 4;
            }

            // DF420 half-cycle ambiguity indicator
            bitPoint += cellNumber;
        }

        if(msmType == 4 || msmType == 5) {
            // DF403 signal CNRs
            for(int i = 0; i < cellNumber; i++) {
                cnrList.add(Utilities.bitToInt(data, bitPoint, 6));
                bitPoint += 6;
            }
        }

        if(msmType == 5) {
            // DF404 signal fine phaserangerate
            bitPoint += 15 * cellNumber;
        }

        if(msmType == 6 || msmType == 7) {
            // DF405 signal fine pseudoranges
            bitPoint += 20 * cellNumber;

            // DF406 signal fine Phaserange
            bitPoint += 24 * cellNumber;

            // DF407 Phaserange Lock Time Indicator
            for(int i = 0; i < cellNumber; i++) {
                ltiList.add(Utilities.bitToInt(data, bitPoint, 10));
                bitPoint += 10;
            }

            // DF420 Half-cycle ambiguity indicator
            bitPoint += cellNumber;

            // DF408 signal CNR	 
            for(int i = 0; i < cellNumber; i++) {
                cnrList.add((int)(Utilities.bitToInt(data, bitPoint, 10) * Math.pow(2, -4)));
                bitPoint += 10;
            }
        }

 //       if(msmType == 5 || msmType == 7) {
 //           // DF404 signal fine PhaseRangeRates
 //           bitPoint += 15 * cellNumber;
 //       }

        return this;
    }

    private int decodeHeader() {
        int bitPoint = HEADER_BYTE_LENGTH * 8;

        // DF002 Message Number
        messageType = Utilities.bitToInt(data, bitPoint, 12);
        bitPoint += 12;

        classifyMSM();

        // DF003 Reference Station ID
        @SuppressWarnings("unused")
        int stationID = Utilities.bitToInt(data, bitPoint, 12);
        bitPoint += 12;

        // GNSS Epoch Time
        if(gnssType == GeoCode.GNSSGLONASS) {
            @SuppressWarnings("unused")
            int dow = Utilities.bitToInt(data, bitPoint, 3);
            epochTime = Utilities.bitToInt(data, bitPoint + 3, 27);
        } else {
            epochTime = Utilities.bitToInt(data, bitPoint, 30);
        }
        bitPoint += 30;

        // MMB:1, IODS:3, Rsv:7, CSI:2, ECI:2, GDSI:1, GSI:3
        bitPoint += 19;

        // DF394  satellite Mask
        satelliteList = getBitMask(data, bitPoint, 64);
        bitPoint += 64;

        // DF395  signal Mask
        signalList = getBitMask(data, bitPoint, 32);
        bitPoint += 32;

        // DF396  cell Mask
        cellMask = Utilities.bitToLong(data, bitPoint, satelliteList.size() * signalList.size());
        bitPoint += satelliteList.size() * signalList.size();

        return bitPoint;
    }

    private List<Integer> getCombinedCellList(List<Integer> target) {
        List<Integer> list = new ArrayList<>();
        int cellLength = satelliteList.size() * signalList.size();
        for(int i = 0, counter = 0; i < satelliteList.size() * signalList.size(); i++) {
            if(((cellMask >> --cellLength) & 0x01) == 1) {
                list.add(target.get(counter++));
            } else {
                list.add(0);
            }
        }
        return list;
    }

    private void classifyMSM() {
        if(messageType >= 1071 && messageType <= 1077) {
            msmType = messageType - 1070; gnssType = GeoCode.GNSSGPS;
        } else if(messageType >= 1081 && messageType <= 1087) {
            msmType = messageType - 1080; gnssType = GeoCode.GNSSGLONASS;
        } else if(messageType >= 1091 && messageType <= 1097) {
            msmType = messageType - 1090; gnssType = GeoCode.GNSSGALILEO;
        } else if(messageType >= 1101 && messageType <= 1107) {
            msmType = messageType - 1100; gnssType = GeoCode.GNSSSBAS;
        } else if(messageType >= 1111 && messageType <= 1117) {
            msmType = messageType - 1110; gnssType = GeoCode.GNSSQZSS;
        } else if(messageType >= 1121 && messageType <= 1127) {
            msmType = messageType - 1120; gnssType = GeoCode.GNSSBEIDOU;
        }
    }
    
    private List<String> getPRNList() {
        int weight;

        switch(gnssType) {
            case GeoCode.GNSSSBAS:
                weight = 119;
                break;
            case GeoCode.GNSSQZSS:
                weight = 192;
                break;
            default:
                weight = 0;
        }

        return satelliteList.stream().map(Object -> Object + weight).map(Object::toString).collect(Collectors.toList());
    }

    private List<Integer> getBitMask(byte[] src, int bitPosition, int bitLength) {
        List<Integer> list = new ArrayList<>();
        int j = 0;
        for(int i = bitPosition; i < bitPosition + bitLength; i++) {
            ++j;
            if(((src[i / 8] >> (7 - i % 8)) & 0x01) == 1) {
                list.add(j);
            }
        }

        return list;
    }

    private String printTable(List<Integer> data) {
        return GeoCode.print2DimensionTable(getPRNList(), getSignalStringList(), data);
    }

    @Override
    String getSuccinctInfo() {
        return GeoCode.getGnssName(gnssType) + " MSM" + msmType +"\r\n" +
                "Satellite: " + getPRNList().size() +
                ",  Signal: " + getSignalStringList().size();
    }

    @Override
    String getAnalyzedString() {
        StringBuilder sb = new StringBuilder();

        sb.append(GeoCode.getGnssName(gnssType)).append(" MSM").append(msmType).append("\r\n");
        sb.append("epochtime: ").append(epochTime).append("\r\n");
        sb.append("satellite: ").append(getPRNList()).append("\r\n");
        sb.append("signal: ").append(getSignalStringList()).append("\r\n");
        if(ltiList.size() > 0) {
            sb.append("Lock Time Indicator\r\n").append(printTable(getCombinedCellList(ltiList))).append("\r\n");
        }
        if(cnrList.size() > 0) {
            sb.append("CNR\r\n").append(printTable(getCombinedCellList(cnrList))).append("\r\n");
        }
        return sb.toString();
    }

    @Override
    public byte[] encode() {
        byte [] bytes = new byte[25];
        return  bytes;
    }

    @SuppressWarnings("unused")
    private String getConvertedEpocTime() {
        return null;
    }

    private List<String> getSignalStringList() {
        List<String> list = new ArrayList<>();
        try {
            for (Integer integer : signalList) {
                list.add(SIGNALMAP[gnssType][integer]);
            }
            return list;
        }catch (Exception e){
        }
        return  list;
    }

    // Getter
    List<Integer> getSatelliteList() {
        return satelliteList;
    }
    List<Integer> getSignalList() {
        return signalList;
    }
    int getGnssType() {
        return gnssType;
    }
    int getMsmType() {
        return msmType;
    }
    int getEpochTime() {
        return epochTime;
    }
    List<Integer> getLtiList() {
        return ltiList;
    }
    List<Integer> getCnrList() {
        return cnrList;
    }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.lang.Math.floor;

public class Utilities {
    private static Logger logger = LoggerFactory.getLogger(Utilities.class);
    public static final int INDEX_NOT_FOUND = -1;

    public static int indexOf(final byte[] dstArray, final byte[] toFind) {
        return indexOf(dstArray, dstArray.length, toFind, 0);
    }


    public static int indexOf(final byte[] dstArray, int dstArrayLength, final byte[] toFind, int startIndex) {
        if (dstArray == null || toFind == null) {
            return INDEX_NOT_FOUND;
        }
        if (startIndex < 0) {
            startIndex = 0;
        }
        if (dstArrayLength > dstArray.length) {
            dstArrayLength = dstArray.length;
        }

        for (int i = startIndex; i < dstArrayLength - toFind.length + 1; i++) {
            boolean found = true;
            for (int j = 0; j < toFind.length; j++) {
                if (dstArray[i + j] != toFind[j]) {
                    found = false;
                    break;
                }
            }
            if (found) {
                return i;
            }
        }
        return INDEX_NOT_FOUND;
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() < 2) {
                sb.append(0);
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    public static byte[] hexToByteArray(String inHex) {
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            hexlen++;
            result = new byte[hexlen / 2];
            inHex = "0" + inHex;
        } else {
            result = new byte[hexlen / 2];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    public static byte hexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }

    public static void set38bits(byte[] buff, int pos, double value) {
        int word_h = (int) (floor(value / 64.0));
        int word_l = (int) (value - word_h * 64.0);
        setbits(buff, pos, 32, word_h);
        setbitu(buff, pos + 32, 6, word_l);
    }

    public static int bitToInt(final byte[] data, int bitPosition, int bitLength) {
        if (data == null || bitLength > 32) {
            return 0;
        }
        int sum = 0;
        for (int i = bitPosition; i < bitPosition + bitLength; i++) {
            sum = (sum << 1) + ((data[i / 8] >> (7 - i % 8)) & 0x01);
        }
        return sum;
    }

    static void setbits(byte[] buff, int pos, int len, int data) {
        if (data < 0) {
            data |= 1 << (len - 1);
            byte[] dataaa = intToByteArray(data);
            logger.info(getBinaryStrFromByte(dataaa));
        } else {
            data &= ~(1 << (len - 1));
        } /* set sign bit */
        setbitu(buff, pos, len, data);
        logger.info(getBinaryStrFromByte2(buff, pos, len));
    }

    public static byte[] intToByteArray(int i) {
        byte[] result = new byte[4];
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }

    public static byte[] LongToBytes(long values) {
        byte[] buffer = new byte[8];
        for (int i = 0; i < 8; i++) {
            int offset = 64 - (i + 1) * 8;
            buffer[i] = (byte) ((values >> offset) & 0xff);
        }
        return buffer;
    }

    public static void intToBit(byte[] buff, int pos, int len, int data) {
        int mask = 1 << (len - 1);
        int i;
        if (len <= 0 || 32 < len) return;
        for (i = pos; i < pos + len; i++, mask >>= 1) {
            if ((data & mask) != 0) {
                buff[i / 8] |= 1 << (7 - i % 8);
            } else {
                buff[i / 8] &= ~(1 << (7 - i % 8));
            }
        }
    }


    public static long bitToLong(byte[] data, int bitPosition, int bitLength) {
        if (data == null || bitLength > 64) {
            return 0;
        }
        long sum = 0;
        for (int i = bitPosition; i < bitPosition + bitLength; i++) {
            sum = (sum << 1) + ((data[i / 8] >> (7 - i % 8)) & 0x01);
        }
        return sum;
    }


    public static void setbitu(byte[] buff, int pos, int len, int data) {
        int mask = 1 << (len - 1);
        int i;
        if (len <= 0 || 32 < len) return;
        for (i = pos; i < pos + len; i++, mask >>= 1) {
            if ((data & mask) != 0) {
                buff[i / 8] |= 1 << (7 - i % 8);
            } else {
                buff[i / 8] &= ~(1 << (7 - i % 8));
            }
        }
    }

    public static long bitToLongMSB(byte[] data, int bitPosition, int bitLength) {
        if (data == null || bitLength > 64) {
            return 0;
        }
        long sum = bitToLong(data, bitPosition, bitLength);
        if (((data[bitPosition / 8] >> (7 - bitPosition % 8)) & 0x01) == 1) {
            long mask = -1L << bitLength;
            sum |= mask;
        }
        return sum;
    }


    public static void longToBitMSB(byte[] data, int bitPosition, double val) {
        long myData = (long) val;
//        logger.info("--"+getBinaryStrFromByte2( LongToBytes(myData),64-38,38));
//        if (val < 0) {
//            myData |= 1 << (63);
//        } else {
//            myData &= ~(1 << 63);
//        } /* set sign bit */
//        logger.info("$$"+getBinaryStrFromByte2( data,bitPosition,38));
//        logger.info("@@"+getBinaryStrFromByte2( LongToBytes(myData),64-38,38));
//                    logger.info(current+"$$"+getBinaryStrFromByte2( data,bitPosition,38));
        byte[] b = LongToBytes(myData);
        for (int m = 0; m < b.length; m++) {
            byte a = b[m];
            for (int i = 0; i < 8; i++) {
                byte c = a;
                a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
                a = (byte) (a << 1);
                int current = m * 8 + i - (64 - 38) + bitPosition;
                if (current >= bitPosition) {
                    if (a == c) {
//                        logger.info(current+"$$0");
                        data[current / 8] &= ~(1 << current % 8);
                    } else {
//                        logger.info(current+"$$1");
                        data[current / 8] |= 1 << current % 8;
                    }

                }
                a = (byte) (a >> 1);
            }
        }
//        logger.info("@@"+getBinaryStrFromByte2( data,bitPosition,38));
        int word_h = (int) (floor(val / 64.0));
        int word_l = (int) (val - word_h * 64.0);
        setbitu(data, bitPosition + 32, 6, word_l);
//        longToBit(data, bitPosition, 38, myData);
//        logger.info("$$"+getBinaryStrFromByte2( data,bitPosition,38));
    }


    public static void longToBit(byte[] buff, int pos, int len, long data) {
        if (len <= 0 || 38 < len) return;
        byte[] b = LongToBytes(data);
        String result = "";
        for (int m = 0; m < b.length; m++) {
            byte a = b[m];
            for (int i = 0; i < 8; i++) {
                if ((m * 8 + i) < 38 || (m * 8 + i) >= 38 + len) {
                    continue;
                }
                byte c = a;
                a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
                a = (byte) (a << 1);
                int current = m * 8 + i - 38 + pos;
                if (a == c) {
                    result = "0" + result;
                    buff[current / 8] |= 1 << (7 - current % 8);
                } else {
                    result = "0" + result;
                    buff[current / 8] &= ~(1 << (7 - current % 8));
                }
                a = (byte) (a >> 1);
            }
        }
        logger.info("**" + result);
    }

    /**
     * 把byte转化成2进制字符串
     *
     * @param b
     * @return
     */
    public static String getBinaryStrFromByte(byte[] b) {
        String result = "";
        for (byte bb : b) {
            byte a = bb;
            for (int i = 0; i < 8; i++) {
                byte c = a;
                a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
                a = (byte) (a << 1);
                if (a == c) {
                    result = "0" + result;
                } else {
                    result = "1" + result;
                }
                a = (byte) (a >> 1);
            }
        }

        return result;
    }


    /**
     * 把byte转化成2进制字符串
     *
     * @param b
     * @return
     */
    public static String getBinaryStrFromByte2(byte[] b, int start, int len) {
        String result = "";
        for (int m = 0; m < b.length; m++) {
            byte a = b[m];
            for (int i = 0; i < 8; i++) {
                if ((m * 8 + i) < start || (m * 8 + i) >= start + len) {
                    continue;
                }
                byte c = a;
                a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。
                a = (byte) (a << 1);
                if (a == c) {
                    result = "0" + result;
                } else {
                    result = "1" + result;
                }
                a = (byte) (a >> 1);
            }
        }

        return result;
    }

    public static byte[] byteConcat(byte[] bt1, byte[] bt2) {
        byte[] bt4 = new byte[bt1.length + bt2.length];
        int len = 0;
        System.arraycopy(bt1, 0, bt4, 0, bt1.length);
        len += bt1.length;
        System.arraycopy(bt2, 0, bt4, len, bt2.length);
        return bt4;
    }
}

欢迎交流,VX:NtripShare

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2222177.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

掌握ElasticSearch(五):查询和过滤器

一、查询和过滤器的区别 在 Elasticsearch 中&#xff0c;查询&#xff08;Query&#xff09;和过滤器&#xff08;Filter&#xff09;是用于检索和筛选数据的重要组成部分。它们虽然都能用来查找文档&#xff0c;但在性能和用法上有所不同。下面详细介绍查询和过滤器的概念以…

Lucas带你手撕机器学习——K近邻

K近邻 (K-Nearest Neighbor KNN) K近邻算法&#xff08;K-Nearest Neighbors, KNN&#xff09;是一种简单直观的机器学习算法&#xff0c;适用于分类和回归问题。它的核心思想是&#xff1a;判断一个数据点的类别或预测值时&#xff0c;参考它在特征空间中最近的 KKK 个数据点…

【2024】【字节青训营】:字节青训营入营测试题——Java版本(已提交通过)

目录 简单题目 计算x到y的最小步数 环状 DNA 序列的最小表示法 Base32 解码和编码 打点计时器 兔群繁殖之谜 完美整数 找出整数数组中占比超过 一半 的数 找出最长的神奇数列 找单独的数 字符串最短循环字串 二进制反码转换问题 中等题目 简单四则运算 数字翻译…

什么是微服务中的反应性扩展?

大家好&#xff0c;我是锋哥。今天分享关于【什么是微服务中的反应性扩展&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 什么是微服务中的反应性扩展&#xff1f; Reactive Extensions 也称为 Rx。这是一种设计方法&#xff0c;我们通过调用多个服务来收集结果…

STM32G474使用TIM2触发DAC输出输出正弦波

STM32G474使用TIM2触发DAC输出&#xff0c;数据从内存到外设就要使用DMA来协助。DAC1每隔1秒输出一个正弦波数据&#xff0c;就会模拟近似得到模拟的正弦波形。用来测试CPU内部的运算放大器&#xff0c;或者用作其它模拟输入信号。 测试程序如下&#xff1a; #include "…

立志最细,FreeRtos的中断管理(Interrupt Management)函数,详解!!!

前言&#xff1a;本文参考&#xff0c;韦东山老师开发文档&#xff0c;连接放在最后。 为什么需要中断管理函数&#xff1f; 在FreeRtos操作系统中&#xff0c;需要实时响应性&#xff0c;也就是随时随地必须保证正常多任务的运行&#xff0c;如果有中断发生&#xff0c;因为中…

Spring Cloud --- Sentinel 规则持久化

为什么要持久化 一旦我们重启微服务应用&#xff0c;sentinel 规则将消失&#xff0c;生产环境需要将配置规则进行持久化 怎么实现持久化 将限流配置规则持久化进 Nacos 保存&#xff0c;只要刷新 8401 某个 rest 地址&#xff0c;sentinel 控制台的流控规则就能看到&#x…

keil新建工程HC32L176MATA

先看一下最后的文件夹结构&#xff08;文件夹结构可以根据项目实际的需要去定义&#xff09; keil内&#xff1a; 参考文章&#xff1a; KEIL平台下新建华大HC32F460单片机工程笔记_hc32f keil环境搭建-CSDN博客 &#xff08;我根据需要&#xff0c;创建的文件夹结构和原文是有…

面试总结一

面试总结 1、自我介绍一下自己2.面试11、css常用布局有哪些2、css常用的属性3.js原型链4、开发中遇到的技术难点5、闭包6、ts了解什么呢7.git都用什么命令8、vue怎么打包9.vue启动一个项目需要什么10、vue怎么创建一个项目 2.面试21.vue2和vue3有什么区别2.复杂组件的封装&…

C#,自动驾驶技术,ASAM OpenDRIVE BS 1.8.0 规范摘要与C# .NET Parser

本文介绍自动驾驶技术的标准之一《ASAM OpenDRIVE》1.8.0 版本的规范摘要&#xff0c;及北京联高软件开发有限公司实现的 C# 版本 xodr 文件&#xff08;XML&#xff09; Parser 源代码。 本文档是 ASAM e.V. 的版权财产。 在更改常规许可条款时&#xff0c;ASAM 允许不受限制地…

gateway 整合 spring security oauth2

微服务分布式认证授权方案 在分布式授权系统中&#xff0c;授权服务要独立成一个模块做统一授权&#xff0c;无论客户端是浏览器&#xff0c;app或者第三方&#xff0c;都会在授权服务中获取权限&#xff0c;并通过网关访问资源 OAuth2的四种授权模式 授权码模式 授权服务器将授…

【原创】统信UOS如何安装最新版Node.js(20.x)

注意直接使用sudo apt install nodejs命令安装十有八九会预装10.x的老旧版本Node.js&#xff0c;如果已经安装的建议删除后安装如下方法重装。 在统信UOS系统中更新Node.js可以通过以下步骤进行&#xff1a; 1. 卸载当前版本的Node.js 首先&#xff0c;如果系统中已经安装了N…

Maven进阶——坐标、依赖、仓库

目录 1.pomxml文件 2. 坐标 2.1 坐标的概念 2.2 坐标的意义 2.3 坐标的含义 2.4 自己项目的坐标 2.5 第三方项目坐标 3. 依赖 3.1 依赖的意义 3.2 依赖的使用 3.3 第三方依赖的查找方法 3.4 依赖范围 3.5 依赖传递和可选依赖 3.5.1 依赖传递 3.5.2 依赖范围对传…

推荐一个开源非线性视频编辑器:Kdenlive

Kdenlive是一个开源的视频编辑软件&#xff0c;项目始于约2003年。它基于Qt和KDE框架库构建&#xff0c;大部分视频处理由MLT框架完成&#xff0c;同时依赖其他开源项目如FFmpeg、frei0r、movit、ladspa、sox等。 软件特点&#xff1a; - 多轨视频编辑&#xff1a;支持多个音频…

大数据新视界 -- 大数据大厂之大数据和增强现实(AR)结合:创造沉浸式数据体验

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

2024 睿抗机器人开发者大赛(RAICOM)-【网络安全】CTF 部分WP

文章目录 一、前言二、MICS你是黑客么循环的压缩包Goodtime 三、WEBpy 四、Crypto变异凯撒RSAcrypto3 一、前言 WP不完整&#xff0c;仅供参考&#xff01; 除WEB&#xff0c;RE&#xff0c;PWN外&#xff0c;其余附件均已打包完毕 也是一个对MISC比较友好的一个比赛~ 123网…

springboot066人事系统(论文+源码)_kaic

基于vue的人事系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;作为学校以及一些培训机构&#xff0c;都在用信息化战术来部署线上学习以及线上考试&#xff0c;可以与线下的考试有机的结合在一起&#xff0c;实现基于vue的人事系统在技术上已成熟。本文介绍…

u盘装win10系统提示“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”解决方法

我们在u盘安装原版win10 iso镜像时&#xff0c;发现在选择硬盘时提示了“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”&#xff0c;直接导致了无法继续安装下去。出现这种情况要怎么解决呢&#xff1f;下面小编分享u盘安装win10系统提示“windows无法安装到这个磁盘…

信息安全工程师(53)网络安全审计机制与实现技术

前言 网络安全审计机制是指为了保护网络安全并发现潜在风险和漏洞而进行的一系列审计活动。审计的目的是检查并评估网络系统的安全性&#xff0c;以确保其符合相关法律法规和安全标准。 一、网络安全审计机制的重要性 网络安全审计机制对于保护组织的信息资产和敏感数据至关重要…

简单的 curl HTTP的POSTGET请求以及ip port连通性测试

简单的 curl HTTP的POST&GET请求以及ip port连通性测试 1. 需求 我们公司有一个演示项目&#xff0c;需要到客户那边进行项目部署&#xff0c;项目部署完成后我们需要进行项目后端接口的测试功能&#xff0c;但是由于客户那边么有条件安装类似于postman这种的测试工具&am…