From 91605535e2a0d2adadea30a6873356e329143f72 Mon Sep 17 00:00:00 2001
From: vincent <1341870251@qq.com>
Date: 星期三, 03 六月 2020 16:53:21 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/common/model/annotations/expr.java   |   16 +
 src/main/java/com/zy/common/utils/Struct.java             |  490 ++++++++++++++++++++++++++++++++++++++++
 src/main/java/com/zy/common/model/annotations/flag.java   |   16 +
 src/main/java/com/zy/common/model/annotations/bit.java    |   16 +
 src/main/java/com/zy/common/model/annotations/little.java |   14 +
 src/main/java/com/zy/common/model/annotations/size.java   |   16 +
 src/main/java/com/zy/common/utils/ReflectUtils.java       |   75 ++++++
 src/main/java/com/zy/common/utils/CommonUtils.java        |   30 ++
 8 files changed, 673 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/zy/common/model/annotations/bit.java b/src/main/java/com/zy/common/model/annotations/bit.java
new file mode 100644
index 0000000..7152fef
--- /dev/null
+++ b/src/main/java/com/zy/common/model/annotations/bit.java
@@ -0,0 +1,16 @@
+package com.zy.common.model.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏍囪瘑娉ㄨВ绫�
+ * @author uiu
+ */
+@Retention(RetentionPolicy.RUNTIME) 
+@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) 
+public @interface bit {
+	int value();
+}
diff --git a/src/main/java/com/zy/common/model/annotations/expr.java b/src/main/java/com/zy/common/model/annotations/expr.java
new file mode 100644
index 0000000..4acd042
--- /dev/null
+++ b/src/main/java/com/zy/common/model/annotations/expr.java
@@ -0,0 +1,16 @@
+package com.zy.common.model.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏍囪瘑娉ㄨВ绫�
+ * @author uiu
+ */
+@Retention(RetentionPolicy.RUNTIME) 
+@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) 
+public @interface expr {
+	String value();
+}
diff --git a/src/main/java/com/zy/common/model/annotations/flag.java b/src/main/java/com/zy/common/model/annotations/flag.java
new file mode 100644
index 0000000..08d4e4b
--- /dev/null
+++ b/src/main/java/com/zy/common/model/annotations/flag.java
@@ -0,0 +1,16 @@
+package com.zy.common.model.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏍囪瘑娉ㄨВ绫�
+ * @author uiu
+ */
+@Retention(RetentionPolicy.RUNTIME) 
+@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) 
+public @interface flag {
+	String value();
+}
diff --git a/src/main/java/com/zy/common/model/annotations/little.java b/src/main/java/com/zy/common/model/annotations/little.java
new file mode 100644
index 0000000..7ecdb45
--- /dev/null
+++ b/src/main/java/com/zy/common/model/annotations/little.java
@@ -0,0 +1,14 @@
+package com.zy.common.model.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 灏忕妯″紡娉ㄨВ绫�
+ * @author uiu
+ */
+@Retention(RetentionPolicy.RUNTIME) 
+@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) 
+public @interface little {}
\ No newline at end of file
diff --git a/src/main/java/com/zy/common/model/annotations/size.java b/src/main/java/com/zy/common/model/annotations/size.java
new file mode 100644
index 0000000..d704ff2
--- /dev/null
+++ b/src/main/java/com/zy/common/model/annotations/size.java
@@ -0,0 +1,16 @@
+package com.zy.common.model.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏍囪瘑娉ㄨВ绫�
+ * @author uiu
+ */
+@Retention(RetentionPolicy.RUNTIME) 
+@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) 
+public @interface size {
+	int value();
+}
diff --git a/src/main/java/com/zy/common/utils/CommonUtils.java b/src/main/java/com/zy/common/utils/CommonUtils.java
new file mode 100644
index 0000000..d3233b7
--- /dev/null
+++ b/src/main/java/com/zy/common/utils/CommonUtils.java
@@ -0,0 +1,30 @@
+package com.zy.common.utils;
+
+import java.math.BigDecimal;
+
+/**
+ * Created by vincent on 2020-06-03
+ */
+public class CommonUtils {
+
+    public static Integer parseInt(Object value){
+        if(null == value){
+            return null;
+        }
+        String name = value.getClass().getSimpleName().toLowerCase();
+        if(name.equals("float")){
+            return ((Float)value).intValue();
+        } else if(name.equals("double")){
+            return ((Double)value).intValue();
+        } else if(name.equals("bigdecimal")) {
+            return ((BigDecimal)value).intValue();
+        } else if(name.equals("long")) {
+            return ((Long)value).intValue();
+        } else if(name.contains("int")) {
+            return (Integer)value;
+        } else {
+            return Double.valueOf(""+value).intValue();
+        }
+    }
+
+}
diff --git a/src/main/java/com/zy/common/utils/ReflectUtils.java b/src/main/java/com/zy/common/utils/ReflectUtils.java
new file mode 100644
index 0000000..470e6e0
--- /dev/null
+++ b/src/main/java/com/zy/common/utils/ReflectUtils.java
@@ -0,0 +1,75 @@
+package com.zy.common.utils;
+
+import com.core.common.Cools;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 鍙嶅皠宸ュ叿绫�
+ * Created by vincent on 2019/1/3
+ */
+public class ReflectUtils {
+
+    /**
+     * 鑾峰彇鎸囧畾Class锛堝強鍏禨uperClass锛夌殑鎴愬憳鍙橀噺
+     */
+    public static Field[] getAllFields(Class<?> cls){
+        return getAllFields(cls, null);
+    }
+
+    /**
+     * 閫掑綊鍚堝苟鍩虹被Field
+     */
+    private static Field[] getAllFields(Class<?> cls, Field[] params){
+        Field[] fields = (params == null) ? cls.getDeclaredFields() : params;
+        Class<?> superCls = cls.getSuperclass();
+        if (superCls == null || superCls == Object.class){
+            return fields;
+        }
+        Field[] superClsFields = superCls.getDeclaredFields();
+        fields = Cools.addAll(fields, superClsFields);
+        return getAllFields(superCls, fields);
+    }
+
+    /**
+     * 鍒犻櫎Field鏁扮粍鐨勯潤鎬佹垚鍛樺彉閲�
+     */
+    public static Field[] removeStaticField(Field[] params){
+        List<Field> fields = new ArrayList<>(Arrays.asList(params));
+        if (fields.size() == 0){
+            return null;
+        }
+        for (int i = fields.size() - 1; i >= 0; i--) {
+            if(fields.get(i) == null){
+                fields.remove(i);
+            } else if (Modifier.isStatic(fields.get(i).getModifiers())) {
+                fields.remove(i);
+                i++;
+            }
+        }
+        return fields.toArray(new Field[0]);
+    }
+
+    /**
+     * 閫掑綊鑾峰彇鎴愬憳鍙橀噺瀵硅薄锛堝寘鍚叾鍩虹被锛�
+     */
+    public static Field getField(Class<?> cls, String fieldName){
+        Field field;
+        try {
+            field = cls.getDeclaredField(fieldName);
+        } catch (NoSuchFieldException e) {
+            Class<?> superCls = cls.getSuperclass();
+            if (superCls == null || superCls == Object.class){
+                return null;
+            }
+            return getField(superCls, fieldName);
+
+        }
+        return field;
+    }
+
+}
diff --git a/src/main/java/com/zy/common/utils/Struct.java b/src/main/java/com/zy/common/utils/Struct.java
new file mode 100644
index 0000000..5f53e28
--- /dev/null
+++ b/src/main/java/com/zy/common/utils/Struct.java
@@ -0,0 +1,490 @@
+package com.zy.common.utils;
+
+import com.zy.common.model.annotations.*;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.util.*;
+
+public class Struct implements java.io.Serializable {
+	
+	private transient Map<String,byte[]> decodeByteMapping = new HashMap<>();
+	private transient Map<String,byte[]> encodeByteMapping = new HashMap<>();
+	private transient byte[] dataBytes = null;
+	private transient byte[] decodeBytes = null;
+	private transient byte[] encodeBytes = null;
+	private transient byte[] unusedBytes = null;
+
+	public Class getClassType(String name){
+		return null;
+	}
+	
+	public boolean isReverse() {
+		return this.getClass().getAnnotation(little.class)!=null;
+	}
+	
+	public byte[] toBytes() throws Exception {
+		return encode(this);
+	}
+	
+	public Map<String,String> toDecodeHexMapping() throws Exception{
+		if(this.decodeByteMapping==null)this.decodeByteMapping=new HashMap();
+		Map<String, String> mapping = getHex(this.decodeByteMapping);
+		if(this.decodeBytes!=null){
+			mapping.put("byte[]", Struct.toHex(this.decodeBytes));
+		}
+		return mapping;
+	}
+	public Map<String,String> toEncodeHexMapping() throws Exception{
+		if(this.encodeBytes==null)this.encode(this);
+		if(this.encodeByteMapping==null)this.encodeByteMapping=new HashMap();
+		Map<String, String> mapping = getHex(this.encodeByteMapping);
+		mapping.put("byte[]", Struct.toHex(this.encodeBytes));
+		return mapping;
+	}
+	public Map<String,String> getHex(Map<String,byte[]> bytemapping) throws Exception {
+		Map<String,String> map = new LinkedHashMap();
+		Field[] fields = this.getClass().getFields();
+		for (Field field : fields) {
+			byte[] bytes = bytemapping.get(field.getName());
+			if(bytes!=null){
+				map.put(field.getName(), Struct.toHex(bytes));
+			}
+		}
+		return map;
+	}
+	
+	// 杞琷ava瀵硅薄鍒版暟缁�
+	public byte[] encode(Struct entity) throws Exception {
+		ByteArrayOutputStream baOs = new ByteArrayOutputStream();
+		write(new DataOutputStream(baOs), entity);
+		entity.encodeBytes = baOs.toByteArray();
+		return entity.encodeBytes;
+	}
+
+	/**
+	 * 鍐欐暟鎹埌杈撳嚭娴�
+	 * 
+	 * @param dos
+	 * @param entity
+	 * @throws Exception
+	 */
+	public void write(DataOutputStream dos, Struct entity) throws Exception {
+		if(entity==null)return;
+		if(entity.encodeByteMapping==null)entity.encodeByteMapping=new HashMap();
+		Field[] fields = entity.getClass().getFields();
+		EvaluationContext context = new StandardEvaluationContext();
+		for (Field field : Objects.requireNonNull(ReflectUtils.removeStaticField(fields))) {
+			field.setAccessible(true);
+			
+			String name = field.getName();
+			Class<?> type = field.getType();
+			String typeName = type.getSimpleName();
+			if(typeName.equals("Struct")){
+				if(entity.getClassType(name)!=null){
+					type = entity.getClassType(name);
+					typeName = type.getSimpleName();
+				}else if(field.get(entity)!=null){
+					type = field.get(entity).getClass();
+					typeName = type.getSimpleName();
+				}
+			}
+			
+			size size = field.getAnnotation(size.class);
+			bit bit = field.getAnnotation(bit.class);
+			expr expr = field.getAnnotation(expr.class);
+			flag flag = field.getAnnotation(flag.class);
+			if(size==null && bit==null && expr==null){
+				continue;
+			}
+			
+			int bited = 0;//宸插啓浣嶆暟
+			int length = 0;//瀹氫箟鐨勯暱搴�
+			if(size!=null){
+				length = size.value();
+				bited+=size.value()*8;
+			}else if(bit!=null){
+				//鎸変綅鍐欐柟寮忔湭瀹炵幇澶勭悊
+				throw new RuntimeException("鎸変綅鍐欐柟寮忔湭瀹炵幇澶勭悊");
+			}else if(expr!=null){
+				ExpressionParser parser = new SpelExpressionParser();
+				Expression exp = parser.parseExpression(expr.value());
+				Integer len = null;
+				try{
+					len = CommonUtils.parseInt(exp.getValue(context, entity));
+				}catch (Exception e){
+					len = 0;
+				}
+				if(len!=null){
+					if(len==-1)continue;
+					length = len;
+					bited+=len*8;
+				}
+			}
+			context.setVariable(name, field.get(entity));
+			
+			byte[] bytes = new byte[length];				
+			
+			if (typeName.equals("int") || typeName.equals("Integer")){
+				dos.write(bytes=convert(length,field.getInt(entity)));
+			}else if (typeName.equals("long") || typeName.equals("Long")){
+				dos.write(bytes=convert(length,field.getLong(entity)));
+			}else if (typeName.equals("short") || typeName.equals("Short")){
+				dos.write(bytes=convert(length,field.getShort(entity)));
+			}else if (typeName.equals("byte") || typeName.equals("Byte")){
+				dos.write(bytes=convert(length,field.getByte(entity)));
+			}else if (typeName.equals("String")) {
+				String str = (String) field.get(entity);
+				if (str == null)
+					str = "";
+				str = str.replaceAll("銆�", " ");
+				
+				byte[] bts = null;
+				if(flag!=null && flag.value().equals("ASCII")){
+					bts = Struct.StrToAsc(str);
+				}else if(flag!=null && flag.value().equals("BCD")){
+					bts = Struct.str2Bcd(str);
+				}else{
+					bts = str.getBytes();
+				}
+				
+				if(length==0){//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
+					bytes = new byte[bts.length];
+				}
+				System.arraycopy(bts, 0, bytes, 0, bts.length);
+				dos.write(bytes);
+			} else if (typeName.equals("byte[]")) {
+				byte[] bts = (byte[]) field.get(entity);
+				if(bts!=null){
+					if(length==0){//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
+						bytes = new byte[bts.length];
+					}
+					System.arraycopy(bts, 0, bytes, 0, bts.length);
+					dos.write(bytes);
+				}
+			}else if (type.isArray()) {
+				ByteArrayOutputStream baOs1 = new ByteArrayOutputStream();
+				DataOutputStream dos1 = new DataOutputStream(baOs1);
+				for (Object object : (Object[]) field.get(entity)){
+					write(dos1, (Struct) object);
+				}
+				byte[] bts  = baOs1.toByteArray();
+				if(length==0){//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
+					bytes = new byte[bts.length];
+				}
+				System.arraycopy(bts, 0, bytes, 0, bts.length);
+				dos.write(bytes);
+			} else {
+				byte[] bts = encode((Struct) field.get(entity));
+				if(length==0){//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
+					bytes = new byte[bts.length];
+				}
+				System.arraycopy(bts, 0, bytes, 0, bts.length);
+				dos.write(bytes);
+			}
+			entity.encodeByteMapping.put(name, bytes);
+		}
+	}
+
+	
+	public byte[] convert(int size, long value) throws Exception{
+		ByteArrayOutputStream baOs = new ByteArrayOutputStream();
+		DataOutputStream dos = new DataOutputStream(baOs);
+		switch(size){
+		case 1://byte
+			dos.write((byte) value);
+			break;
+		case 2://short
+			dos.writeShort(this.isReverse() ? Short.reverseBytes((short)value) : (short)value);
+			break;
+		case 4://int
+			dos.writeInt(this.isReverse() ? Integer.reverseBytes((int)value) : (int)value);
+			break;
+		case 8://long
+			dos.writeLong(this.isReverse() ? Long.reverseBytes((long)value) : (long)value);
+			break;
+		}
+		return baOs.toByteArray();
+	}
+	
+	public long convertEx(long value,int size) throws Exception{
+		switch(size){
+		case 1://byte
+			return value;
+		case 2://short
+			return (this.isReverse() ? Short.reverseBytes((short)value) : (short)value);
+		case 4://int
+			return (this.isReverse() ? Integer.reverseBytes((int)value) : (int)value);
+		case 8://long
+			return (this.isReverse() ? Long.reverseBytes((long)value) : (long)value);
+		}
+		return 0;
+	}
+	
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static <T extends Struct> T decode(Class<? extends Struct> cls,byte[] bytes) throws Exception{
+		Struct instance = cls.newInstance();
+		return instance.decode(bytes);
+	}
+
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public <T extends Struct> T decode(byte[] bytes) throws Exception{
+		this.dataBytes = bytes;
+		Struct instance = this;
+		Class<? extends Struct> cls = this.getClass();
+		Field[] fields = cls.getFields();
+		if(this.decodeByteMapping==null)instance.decodeByteMapping=new HashMap();
+		EvaluationContext context = new StandardEvaluationContext();
+		context.setVariable("_", bytes.length);
+		int bited = 0;//宸茶浣嶆暟
+		for(Field field: Objects.requireNonNull(ReflectUtils.removeStaticField(fields))){
+			size size = field.getAnnotation(size.class);
+			bit bit = field.getAnnotation(bit.class);
+			expr expr = field.getAnnotation(expr.class);
+			flag flag = field.getAnnotation(flag.class);
+			if(size==null && bit==null && expr==null){
+				continue;
+				//throw new RuntimeException(cls.getSimpleName()+"瀛楁"+field.getName()+"鏈爣璁癅size|@bit|@expr");
+			}
+			String name = field.getName();
+			Class<?> type = field.getType();
+			String typeName = type.getSimpleName();
+			if(typeName.equals("Struct")){
+				if(instance.getClassType(name)!=null){
+					type = instance.getClassType(name);
+					typeName = type.getSimpleName();
+				}
+			}
+			context.setVariable("__", bytes.length-bited/8);
+			byte[] bts = null;
+			if(size!=null){
+				bts = new byte[size.value()];
+				System.arraycopy(bytes, bited/8, bts, 0, size.value());
+				bited+=size.value()*8;
+			}else if(bit!=null){
+				int val = 0;
+				String strBin = "";
+				for(int i=bited;i<bited+bit.value();i++){//閫愪綅鎵弿
+					if((bytes[i/8] & (1 << (i%8))) != 0){//濡傛灉浣嶄负1
+						strBin+="1";
+					}else{
+						strBin+="0";
+					}
+					val = Integer.parseInt(strBin, 2);
+				}				
+				byte[] result = new byte[4];
+				result[3] = (byte)(val);
+				result[2] = (byte)(val >> 8);
+				result[1] = (byte)(val >> 16);
+				result[0] = (byte)(val >> 24);
+				bts = new byte[(int)Math.ceil((double)bit.value()/8.0)];
+				System.arraycopy(result, result.length-bts.length, bts, 0, bts.length);
+				bited+=bit.value();
+			}else if(expr!=null){
+				ExpressionParser parser = new SpelExpressionParser();
+				Expression exp = parser.parseExpression(expr.value());
+				Integer len = CommonUtils.parseInt(exp.getValue(context,instance));
+				if(len!=null){
+					if(len==-1)continue;
+					bts = new byte[len];
+					System.arraycopy(bytes, bited/8, bts, 0, len);
+					bited+=len*8;
+				}
+			}
+			if(bts.length==0)continue;
+			DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bts));
+			if (typeName.equals("int") || typeName.equals("Integer")){
+				field.setInt(instance,(int) convertEx(dis.readInt(),4));
+			}else if (typeName.equals("long") || typeName.equals("Long")){
+				field.setLong(instance, convertEx(dis.readLong(),8));
+			}else if (typeName.equals("short") || typeName.equals("Short")){
+				field.setShort(instance, (short) convertEx(dis.readShort(),2));
+			}else if (typeName.equals("byte") || typeName.equals("Byte")){
+				field.setByte(instance, (byte) convertEx(dis.readByte(),1));
+			}else if (typeName.equals("byte[]")){
+				field.set(instance, bts);
+			}else if (typeName.equals("String")) {
+				String strStr = new String(bts,"UTF-8");
+				if(flag!=null && flag.value().equals("BCD")){
+					strStr = bcd2Str(bts);
+				}else if(flag!=null && flag.value().equals("ASCII")){
+					strStr = Struct.AscToStr(bts);
+				}
+				strStr = strStr.replaceAll("[\u0000]", "");
+				field.set(instance, strStr);
+			}else if (type.isArray()) {
+				byte[] arrayBytes = bts;
+				List list = new ArrayList();
+				while(arrayBytes.length>0 && list.size()<256){
+					Struct item = decode((Class<? extends Struct>) type.getComponentType(),arrayBytes);
+					list.add(item);
+					arrayBytes = item.unusedBytes;
+				}
+				Object array = Array.newInstance(type.getComponentType(), list.size());
+				for(int i=0;i<list.size();i++){
+					Array.set(array, i, list.get(i));
+				}
+				field.set(instance, array);
+			}else if(type==Struct.class || Struct.class.isAssignableFrom(type)){
+				byte[] arrayBytes = bts;
+				Struct item = decode((Class<? extends Struct>) type,arrayBytes);
+				field.set(instance, item);
+			}else{
+				throw new RuntimeException(cls.getSimpleName()+"瀛楁"+field.getName()+"绫诲瀷鏈煡");
+			}
+			instance.decodeByteMapping.put(name, bts);
+			context.setVariable(name, field.get(instance));
+		}
+		byte[] useBytes = new byte[bited/8];
+		System.arraycopy(bytes, 0 , useBytes, 0, bited/8);
+		instance.decodeBytes = useBytes;
+		byte[] unusedBytes = new byte[bytes.length-(bited/8)];
+		if(unusedBytes.length>0){
+			System.arraycopy(bytes, useBytes.length , unusedBytes, 0, unusedBytes.length);
+		}
+		instance.unusedBytes = unusedBytes;
+		return (T) instance;
+	}
+	public static String toHex(byte[] bytes) {
+        StringBuilder buf = new StringBuilder(bytes.length * 2);
+        for(byte b : bytes) { // 浣跨敤String鐨刦ormat鏂规硶杩涜杞崲
+            buf.append(String.format("%02x", new Integer(b & 0xff)));
+        }
+        return buf.toString().toUpperCase();
+    }
+    public static byte[] toBytes(String str) {
+        if(str == null || str.trim().equals("")) return new byte[0];
+        byte[] bytes = new byte[str.length() / 2];
+        for(int i = 0; i < str.length() / 2; i++) {
+            String subStr = str.substring(i * 2, i * 2 + 2);
+            bytes[i] = (byte) Integer.parseInt(subStr, 16);
+        }
+        return bytes;
+    }
+	
+    
+    
+    /**
+	 * @鍔熻兘: BCD鐮佽浆涓�10杩涘埗涓�(闃挎媺浼暟鎹�)
+	 * @鍙傛暟: BCD鐮�
+	 * @缁撴灉: 10杩涘埗涓�
+	 */
+	public static String bcd2Str(byte[] bytes) {
+		StringBuffer temp = new StringBuffer(bytes.length * 2);
+		for (int i = 0; i < bytes.length; i++) {
+			temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
+			temp.append((byte) (bytes[i] & 0x0f));
+		}
+		return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
+				.toString().substring(1) : temp.toString();
+	}
+
+	/**
+	 * @鍔熻兘: 10杩涘埗涓茶浆涓築CD鐮�
+	 * @鍙傛暟: 10杩涘埗涓�
+	 * @缁撴灉: BCD鐮�
+	 */
+	public static byte[] str2Bcd(String asc) {
+		int len = asc.length();
+		int mod = len % 2;
+		if (mod != 0) {
+			asc = "0" + asc;
+			len = asc.length();
+		}
+		byte abt[] = new byte[len];
+		if (len >= 2) {
+			len = len / 2;
+		}
+		byte bbt[] = new byte[len];
+		abt = asc.getBytes();
+		int j, k;
+		for (int p = 0; p < asc.length() / 2; p++) {
+			if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
+				j = abt[2 * p] - '0';
+			} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
+				j = abt[2 * p] - 'a' + 0x0a;
+			} else {
+				j = abt[2 * p] - 'A' + 0x0a;
+			}
+			if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
+				k = abt[2 * p + 1] - '0';
+			} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
+				k = abt[2 * p + 1] - 'a' + 0x0a;
+			} else {
+				k = abt[2 * p + 1] - 'A' + 0x0a;
+			}
+			int a = (j << 4) + k;
+			byte b = (byte) a;
+			bbt[p] = b;
+		}
+		return bbt;
+	}
+    
+    
+    public static class TestMessage {
+		public @size(1) byte begin = 0x7e;//璧峰绗�
+		public @size(2) short type = 0;//娑堟伅ID
+		public @bit(2) byte retain;//娑堟伅浣撳睘鎬�>淇濈暀
+		public @bit(1) byte subpkg;//娑堟伅浣撳睘鎬�>鏄惁鍒嗗寘,0琛ㄧず涓嶅垎鍖�
+		public @bit(3) byte encrypt;//娑堟伅浣撳睘鎬�>鍔犲瘑鏂瑰紡,0琛ㄧず涓嶅姞瀵�
+		public @bit(10) short length;//娑堟伅浣撻暱搴�
+		public @size(6) @flag("BCD") String number;//鎵嬫満鍙风爜
+		public @size(2) short serial;//娑堟伅娴佹按鍙�
+		public @expr("#subpkg==1?2:0") short pkgs;//鍒嗗寘鏁�
+		public @expr("#subpkg==1?2:0") short index;//鍖呭簭鍙�
+		public @expr("#length") byte[] data;//鏁版嵁閮ㄥ垎
+		public @size(1) byte verify;//鏍¢獙鐮�
+		public @size(1) byte end = 0x7e;//缁撴潫绗�
+	}
+    
+    public static byte getXor(byte[] datas,int start, int end){
+    	byte temp=datas[start];
+    	for (int i = start+1; i <end; i++) {
+    		temp ^=datas[i];
+    	}
+    	return temp;
+    }
+
+    
+    /**
+     * 姹傛牎楠屽拰鐨勭畻娉�
+     * @param b 闇�瑕佹眰鏍¢獙鍜岀殑瀛楄妭鏁扮粍
+     * @return 鏍¢獙鍜�
+     */
+    public static byte sumCheck(byte[] b,int start, int end){
+        int sum = 0;
+        for(int i = start; i < end; i++){
+            sum = sum + b[i];
+        }
+        return (byte) (sum & 0xff);
+    }
+    
+  //瀛楃涓茶浆鎹负ascii
+    public static byte[] StrToAsc(String content){
+      try {
+		return content.getBytes("US-ASCII");
+	} catch (Exception e) {
+		e.printStackTrace();
+		return null;
+	}
+    }
+   
+    //ascii杞崲涓簊tring
+    public static String AscToStr(byte[] bytes){
+    	StringBuffer sbu = new StringBuffer();  
+    	for(int i=0;i<bytes.length;i++){
+    		sbu.append(Character.toString((char)bytes[i]));
+    	}
+        return sbu.toString(); 
+    }
+
+}
\ No newline at end of file

--
Gitblit v1.9.1