Files
min-dev-java/src/main/java/encoding/VlInt.java
T

247 lines
7.7 KiB
Java

package encoding;
import util.ByteHelper;
import java.math.BigInteger;
import static java.lang.Math.pow;
/*
* @Author: Wang Feng
* @Description:变长无符号整型,用于表示TLV中的T和L
* @Version: 1.0.0
* @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
*/
public int SizeOfVarNumber(){
return SizeOfVarNumber(this.VlIntValue);
}
private static int SizeOfVarNumber(BigInteger bigInteger){
if(bigInteger.compareTo(BigInteger.valueOf(241)) < 0){
return 1;
}else if(bigInteger.compareTo(BigInteger.valueOf(
new Double(pow(2, 16)).longValue())) < 0){
return 3;
}else if(bigInteger.compareTo(BigInteger.valueOf(
new Double(pow(2, 32)).longValue())) < 0){
return 5;
}else{ //MIN1.0中,VlInt的size最大为9
return 9;
}
}
//todo:判断bytes是否是一个合法的变长非负整型
//todo:判断biginteger是否合法
public VlInt(byte[] bytes){
this.VlIntBytes=bytes;
this.VlIntValue=vlintBytes2bigInteger(bytes);
}
public VlInt(BigInteger bigInteger){
this.VlIntValue=bigInteger;
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);
}
// 传入一个BigInteger,将它解析成一个VlInt
public VlInt createVlIntByBigInteger(BigInteger bigInteger){
return new VlInt(bigInteger);
}
/**
* 将vlint转为一个int输出:需要判断size是不是小于4(1 or 3)
* @return
*/
public int getVlIntValue2Int(){
if(this.SizeOfVarNumber()<4){
return VlIntValue.intValue();
}
return Integer.parseInt(null);
}
/**
* 将vlint转为一个long输出:需要判断size是不是小于8(5)
* @return
*/
public long getVlIntValue2Long(){
if(this.SizeOfVarNumber()<8){
return VlIntValue.longValue();
}
return Long.parseLong(null);
}
/**
* 将vlint转为一个biginteger输出:需要判断size是不是等于9(9)
* @return
*/
public BigInteger getVlIntValue(){
if(this.SizeOfVarNumber()>=9){
return VlIntValue;
}
return null;
}
/**
* 判断vlint是否与某个值相等
* @param vlInt
* @return
*/
public boolean isEqual(VlInt vlInt){
if(this.VlIntValue.compareTo(vlInt.VlIntValue)==0){
return true;
}
return false;
}
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的数值孰大孰小
* @param vlInt
* @return
*/
public int compareTo(VlInt vlInt){
return this.VlIntValue.compareTo(vlInt.VlIntValue);
}
public int compareTo(int 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);
}
/**
* 减去另一个VlInt
* todo:暂没考虑两者差值越界int最大值
* @param vlInt
* @return
*/
public int subtract(VlInt vlInt){
return this.VlIntValue.subtract(vlInt.VlIntValue).intValue();
}
/**
* 增加VlInt
* @param vlInt
* @return
*/
public int add(VlInt vlInt){
return this.VlIntValue.add(vlInt.VlIntValue).intValue();
}
/**
* 将BigInteger转为byte[按照变长无符号整数方式转]
* @param bigInteger
* @return
*/
private byte[] bigInteger2vlintBytes(BigInteger bigInteger){
byte[] vlintbytes;
if(SizeOfVarNumber(bigInteger)==1){
vlintbytes=new byte[1];
vlintbytes[0]= ByteHelper.uint8ToByte(bigInteger.intValue());
}else if(SizeOfVarNumber(bigInteger)==3){
vlintbytes=new byte[3];
vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend2);
System.arraycopy(ByteHelper.uint16ToByteArray(bigInteger.intValue()),0,vlintbytes,1,2);
}else if(SizeOfVarNumber(bigInteger)==5){
vlintbytes=new byte[5];
vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend4);
System.arraycopy(ByteHelper.uint32ToByteArray(bigInteger.longValue()),0,vlintbytes,1,4);
}else{
vlintbytes=new byte[9];
vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend8);
System.arraycopy(ByteHelper.uint64ToByteArray(bigInteger.longValue()),0,vlintbytes,1,8);
}
return vlintbytes;
}
/**
* 将变长无符号整数数组转为BigInteger
* @param vlIntBytes
* @return
*/
private BigInteger vlintBytes2bigInteger(byte[] vlIntBytes){
BigInteger vlintValue;
if(vlIntBytes.length==1){
long value=ByteHelper.uint8ToLong(vlIntBytes[0]);
vlintValue=BigInteger.valueOf(value);
}else if(vlIntBytes.length==3){
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){
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){
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;
}
return vlintValue;
}
// 测试
public static void main(String[] args){
BigInteger bigInteger=new BigInteger("3");
VlInt vlInt=new VlInt(bigInteger);
System.out.println(vlInt.isEqual(2));
}
}