diff --git a/src/encoding/TLV.java b/src/encoding/TLV.java index 61983a9..ee22df5 100644 --- a/src/encoding/TLV.java +++ b/src/encoding/TLV.java @@ -1,8 +1,6 @@ package encoding; -import static util.ByteHelper.getFirstByte; -import static util.ByteHelper.getLenBytes; -import static util.ByteHelper.unsignedbyte2int; +import static util.ByteHelper.*; /* * @Author: Wang Feng @@ -79,7 +77,7 @@ public class TLV { return null; } - int firstbyte=unsignedbyte2int(getFirstByte(buffer,start)); + int firstbyte=uint8ToInt(getFirstByte(buffer,start)); if(firstbyte<241){ return new VlInt(firstbyte); }else if(firstbyte==241){ diff --git a/src/encoding/VlInt.java b/src/encoding/VlInt.java index 8e35243..ff098f7 100644 --- a/src/encoding/VlInt.java +++ b/src/encoding/VlInt.java @@ -1,5 +1,7 @@ package encoding; +import util.ByteHelper; + import java.math.BigInteger; import static java.lang.Math.pow; @@ -11,12 +13,24 @@ import static java.lang.Math.pow; * @Date: 18:13 2021/3/1 * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ + public class VlInt { // 实际传输的数据 private byte[] VlIntBytes; // 变长整数表示的真实数值 private BigInteger VlIntValue; + // 一些int常量 + // @Description: + // 1. x < 240 => 1字节表示 => 230 + // 2. 241 =< x < uint16::Max => 第一个字节为241,后面连着2字节表示实际数值,总共用3个字节表示 => 246 + // 3. uint16::Max =< x < uint32::Max => 第一个字节为242,后面连着4字节表示实际数值,总共用5个字节表示 + // 4. int32::Max =< x < int64::Max => 第一个字节为243,后面连着8字节表示实际数值,总共用9个字节表示 + // 5. 后续还留有12个字节可以进行指数级扩展,目前留空 + public static final int VlIntExtend2=241; + public static final int VlIntExtend4=242; + public static final int VlIntExtend8=243; + /** * 测量一个变长整型实际用几个字节表示 * @return @@ -52,6 +66,16 @@ public class VlInt { this.VlIntBytes=bigInteger2vlintBytes(bigInteger); } + public VlInt(int i){ + this.VlIntValue=BigInteger.valueOf(i); + this.VlIntBytes=bigInteger2vlintBytes(this.VlIntValue); + } + + public VlInt(long l){ + this.VlIntValue=BigInteger.valueOf(l); + this.VlIntBytes=bigInteger2vlintBytes(this.VlIntValue); + } + // 传入一个变长无符号字节数组byte[],将它解析成一个VlInt public VlInt createVlInt(byte[] bytes){ return new VlInt(bytes); @@ -62,31 +86,32 @@ public class VlInt { return new VlInt(bigInteger); } - // todo:传入一个int,将它解析成一个VlInt - public VlInt(int i){ - this.VlIntValue=new BigInteger(String.valueOf(i)); - this.VlIntBytes=bigInteger2vlintBytes(this.VlIntValue); - } - - // todo:传入一个long,将它解析成一个VlInt - - // 将vlint转为一个int输出:需要判断size是不是小于4(1 or 3) - public Integer getVlIntValue2Int(){ + /** + * 将vlint转为一个int输出:需要判断size是不是小于4(1 or 3) + * @return + */ + public int getVlIntValue2Int(){ if(this.SizeOfVarNumber()<4){ return VlIntValue.intValue(); } - return null; + return Integer.parseInt(null); } - // 将vlint转为一个long输出:需要判断size是不是小于8(5) - public Long getVlIntValue2Long(){ + /** + * 将vlint转为一个long输出:需要判断size是不是小于8(5) + * @return + */ + public long getVlIntValue2Long(){ if(this.SizeOfVarNumber()<8){ return VlIntValue.longValue(); } - return null; + return Long.parseLong(null); } - // 将vlint转为一个biginteger输出:需要判断size是不是等于9(9) + /** + * 将vlint转为一个biginteger输出:需要判断size是不是等于9(9) + * @return + */ public BigInteger getVlIntValue(){ if(this.SizeOfVarNumber()>=9){ return VlIntValue; @@ -94,24 +119,29 @@ public class VlInt { return null; } - // 判断vlint是否与某个int值相等 - public boolean isEqual(Integer vlint){ - return isEqual(vlint.intValue()); - } - public boolean isEqual(int i){ - if(this.VlIntValue.compareTo(new BigInteger(String.valueOf(i)))==0){ - return true; - } - return false; - } + /** + * 判断vlint是否与某个值相等 + * @param vlInt + * @return + */ public boolean isEqual(VlInt vlInt){ if(this.VlIntValue.compareTo(vlInt.VlIntValue)==0){ return true; } return false; } - - // todo: 判断vlint是否与某个long值相等 + public boolean isEqual(int i){ + if(this.VlIntValue.compareTo(BigInteger.valueOf(i))==0){ + return true; + } + return false; + } + public boolean isEqual(long l){ + if(this.VlIntValue.compareTo(BigInteger.valueOf(l))==0){ + return true; + } + return false; + } /** * 判断与另一个VlInt的数值孰大孰小 @@ -122,7 +152,11 @@ public class VlInt { return this.VlIntValue.compareTo(vlInt.VlIntValue); } public int compareTo(int i){ - BigInteger bigInteger=new BigInteger(String.valueOf(i)); + BigInteger bigInteger=BigInteger.valueOf(i); + return this.VlIntValue.compareTo(bigInteger); + } + public int compareTo(long l){ + BigInteger bigInteger=BigInteger.valueOf(l); return this.VlIntValue.compareTo(bigInteger); } @@ -136,36 +170,57 @@ public class VlInt { return this.VlIntValue.subtract(vlInt.VlIntValue).intValue(); } - // 将BigInteger转为byte[按照变长无符号整数方式转] + /** + * 将BigInteger转为byte[按照变长无符号整数方式转] + * @param bigInteger + * @return + */ private byte[] bigInteger2vlintBytes(BigInteger bigInteger){ byte[] vlintbytes; if(SizeOfVarNumber(bigInteger)==1){ vlintbytes=new byte[1]; - //todo + vlintbytes[0]= ByteHelper.uint8ToByte(bigInteger.intValue()); }else if(SizeOfVarNumber(bigInteger)==3){ vlintbytes=new byte[3]; - //todo + vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend2); + System.arraycopy(ByteHelper.uint16ToByteArray(bigInteger.intValue()),0,vlintbytes,1,2); }else if(SizeOfVarNumber(bigInteger)==5){ vlintbytes=new byte[5]; - //todo + vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend4); + System.arraycopy(ByteHelper.uint32ToByteArray(bigInteger.longValue()),0,vlintbytes,1,4); }else{ vlintbytes=new byte[9]; - //todo + vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend8); + System.arraycopy(ByteHelper.uint64ToByteArray(bigInteger.longValue()),0,vlintbytes,1,8); } return vlintbytes; } - // 将变长无符号整数数组转为BigInteger + /** + * 将变长无符号整数数组转为BigInteger + * @param vlIntBytes + * @return + */ private BigInteger vlintBytes2bigInteger(byte[] vlIntBytes){ - BigInteger vlintValue=null; + BigInteger vlintValue; if(vlIntBytes.length==1){ - //todo + long value=ByteHelper.uint8ToLong(vlIntBytes[0]); + vlintValue=BigInteger.valueOf(value); }else if(vlIntBytes.length==3){ - //todo + byte[] valueByte=new byte[2]; + System.arraycopy(vlIntBytes,1,valueByte,0,valueByte.length); + long value=ByteHelper.uint16ToLong(valueByte); + vlintValue=BigInteger.valueOf(value); }else if(vlIntBytes.length==5){ - //todo + byte[] valueByte=new byte[4]; + System.arraycopy(vlIntBytes,1,valueByte,0,valueByte.length); + long value=ByteHelper.uint32ToLong(valueByte); + vlintValue=BigInteger.valueOf(value); }else if(vlIntBytes.length==9){ - //todo + byte[] valueByte=new byte[8]; + System.arraycopy(vlIntBytes,1,valueByte,0,valueByte.length); + long value=ByteHelper.uint64ToLong(valueByte); + vlintValue=BigInteger.valueOf(value); }else{ return null; } diff --git a/src/encoding/VlInt_V1.java b/src/encoding/VlInt_V1.java index 755e5b4..69e9f97 100644 --- a/src/encoding/VlInt_V1.java +++ b/src/encoding/VlInt_V1.java @@ -14,8 +14,8 @@ public class VlInt_V1 { // 实际传输的数据 private byte[] VlIntByte; // 变长整数表示的真实数值: - // MIN1.0最大为(2^64-1) - private double VlIntValue; + // MIN1.0最大为(2^64-1),此处用long表示,则可能发生越界 + private long VlIntValue; // 传入一个变长无符号字节数组byte[],将它解析成一个VlInt diff --git a/src/util/ByteHelper.java b/src/util/ByteHelper.java index 70ce32a..47703a0 100644 --- a/src/util/ByteHelper.java +++ b/src/util/ByteHelper.java @@ -21,7 +21,7 @@ public class ByteHelper { public static byte getFirstByte(byte[] buffer, VlInt start){ int startInt=start.getVlIntValue2Int(); byte[] firstbyte=new byte[1]; - System.arraycopy(buffer,startInt,firstbyte,0,1); + System.arraycopy(buffer,startInt,firstbyte,0,firstbyte.length); return firstbyte[0]; } @@ -46,13 +46,226 @@ public class ByteHelper { return lenbytes; } + /** + * 无符号int转byte[] + * @param i_int + * @return + */ + private static byte[] intToByteArray(int i_int) { + byte[] result = new byte[4]; + //由高位到低位 + for(int i=0;i<4;i++) { + int offset=(result.length-i-1)*8; + result[i] = (byte) ((i_int >>>offset) & 0xff); + } + return result; + } + + /** + * 无符号byte[]转int + * @param bytes + * @return + */ + private static int byteArrayToInt(byte[] bytes) { + if(bytes.length!=4){ + return Integer.parseInt(null); + } + int value= 0; + //由高位到低位 + for (int i = 0; i < 4; i++) { + int offset= (bytes.length - 1 - i) * 8; + value +=(bytes[i] & 0x000000ff) << offset; //往高位游 + } + return value; + } + + /** + * 无符号long转byte[] + * @param l_long + * @return + */ + private static byte[] longToByteArray(long l_long) { + byte[] result = new byte[8]; + for (int i = 0; i<8; i++) { + int offset = (result.length - 1 - i) * 8; + result[i] = (byte) ((l_long >>> offset) & 0xff); + } + return result; + } + + /** + * 无符号byte[]转long + * @param bytes + * @return + */ + private static long byteArrayToLong(byte[] bytes) { + if(bytes.length!=8){ + return Integer.parseInt(null); + } + int value= 0; + //由高位到低位 + for (int i = 0; i < 8; i++) { + int offset= (bytes.length - 1 - i) * 8; + value +=(bytes[i] & 0x000000000000ff) << offset; //往高位游 + } + return value; + } + /** * 无符号字节转int * @param b * @return */ - public static int unsignedbyte2int(byte b){ - return (int) b; +// private static int unsignedbyte2int(byte b){ +// return (int) b&0xff; +// } + + /** + * uint8转int + * @param uint8 + * @return + */ + public static int uint8ToInt(byte uint8){ + return uint8 & 0xff; + } + + /** + * 一个uint8转为的int,通过本函数再次转为byte + * @param uint8 + * @return + */ + public static byte uint8ToByte(int uint8){ + return (byte)(uint8 & 0xff); + } + + /** + * uint8转long + * @param uint8 + * @return + */ + public static long uint8ToLong(byte uint8){ + return uint8ToInt(uint8); + } + + /** + * uint16转int + * @param uint16 + * @return + */ + public static int uint16ToInt(byte[] uint16){ + if(uint16.length!=2){ + return Integer.parseInt(null); + } + byte[] bytes=new byte[4]; + for(int i=0;i<2;i++) { + bytes[i] = 0x00; + } + System.arraycopy(uint16,0,bytes,2,uint16.length); + return byteArrayToInt(bytes); + } + + /** + * 一个uint16转为的int,通过本函数再次转为byte[] + * @param uint16 + * @return + */ + public static byte[] uint16ToByteArray(int uint16){ + byte[] result = new byte[2]; + for (int i = 0; i<2; i++) { + int offset = (result.length - 1 - i) * 8; + result[i] = (byte) ((uint16 >>> offset) & 0xff); + } + return result; + } + + /** + * uint16转long + * @param uint16 + * @return + */ + public static long uint16ToLong(byte[] uint16){ + return uint16ToInt(uint16); + } + + /** + * uint32转long + * @param uint32 + * @return + */ + public static long uint32ToLong(byte[] uint32){ + if(uint32.length!=4){ + return Long.parseLong(null); + } + byte[] bytes=new byte[64]; + for(int i=0;i<4;i++) { + bytes[i] = 0x00; + } + System.arraycopy(uint32,0,bytes,4,uint32.length); + return byteArrayToLong(bytes); + } + + /** + * 一个uint32转为的long,通过本函数再次转为byte[] + * @param uint32 + * @return + */ + public static byte[] uint32ToByteArray(long uint32){ + byte[] result = new byte[4]; + for (int i = 0; i<4; i++) { + int offset = (result.length - 1 - i) * 8; + result[i] = (byte) ((uint32 >>> offset) & 0xff); + } + return result; + } + + /** + * uint64转long + * todo: 理论上可能发生越界 + * @param uint64 + * @return + */ + public static long uint64ToLong(byte[] uint64){ + if(uint64.length!=8){ + return Long.parseLong(null); + } + return byteArrayToLong(uint64); + } + + /** + * 一个uint64转为的long,通过本函数再次转为byte[] + * todo: 理论上可能发生越界 + * @param uint64 + * @return + */ + public static byte[] uint64ToByteArray(long uint64){ + byte[] result = new byte[8]; + for (int i = 0; i<8; i++) { + int offset = (result.length - 1 - i) * 8; + result[i] = (byte) ((uint64 >>> offset) & 0xff); + } + return result; + } + + // short整型转为byte类型的数组 +// private static byte[] unsigned_short_2byte(int length) { +// byte[] targets = new byte[2]; +// for (int i = 0; i < 2; i++) { +// int offset = (targets.length - 1 - i) * 8; +// targets[i] = (byte) ((length >>> offset) & 0xff); +// } +// return targets; +// } + + //测试:对于uint8,应当测试1 127 128 + public static void main(String[] args){ + +// byte[] testBytes={0x01,0x02}; +// for(int i=0;i<2;i++) { +// System.out.println(testBytes[i]&0xFF); +//// System.out.println(Integer.toHexString(testBytes[i]&0xFF)); +// } + byte b=-1; + System.out.println(b&0xff); } }