最近有点累,一直在摸鱼,想在平差方面做点事情,但是一直在构思应该怎么去做,有想法的朋友可以交流。
收到了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开源项目实在是太少了,真的只能手撸。这次的代码开放一部分,以便大家少走弯路。
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;
}
}
java
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;
}
}
java
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