欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hex Bytes UltraEditHex十六进制二进制 

程序员文章站 2024-03-21 20:46:58
...

 

好些年前写的,偶然找出来,临时用下,顺便分享下~~  性能好像不咋地 

 

import java.io.ByteArrayOutputStream;

public class UltraEdit {
	public static void main(String[] args) {
		System.out.println(UltraEdit.getInstance().getHexUpperCase(" 测试 & 数据 Test Data".getBytes()));
		System.out.println(UltraEdit.getInstance().b2HEX(" 测试 & 数据 Test Data".getBytes(),":"));
		String hex = UltraEdit.getInstance().b2HEX(" 测试 & 数据 Test Data".getBytes());
		System.out.println(hex);
		System.out.println(new String(UltraEdit.getInstance().hex2b(hex)));
		
		UltraEdit.getInstance().hex2b("F");
	}
	
	
	private final static UltraEdit instance = new UltraEdit(); 
	
	private UltraEdit() {
		Configuration.byte2HexUpper = new Byte2HexUpper();
		Configuration.byte2HexLower = new Byte2HexLower();
		Configuration.byte2ASCII = new Byte2ASCII();
	}
	
	public synchronized static UltraEdit getInstance() {
		return instance;
	}
	
	public String getHexUpperCase(byte[] data) {
		return byte2HexFormat(data, 16, Configuration.byte2HexUpper,Configuration.byte2ASCII);
	}	
	
	public String getHexLowerCase(byte[] data) {
		return byte2HexFormat(data, 16, Configuration.byte2HexLower,Configuration.byte2ASCII);
	}
	
	public String getHexUpperCase(byte[] data,int width) {
		return byte2HexFormat(data, width, Configuration.byte2HexUpper,Configuration.byte2ASCII);
	}
	
	public String getHexLowerCase(byte[] data,int width) {
		return byte2HexFormat(data, width, Configuration.byte2HexLower,Configuration.byte2ASCII);
	}
	
	/** 将byte[]数据以十六进制的形式显示,显示格式仿照UltraEdit*/
	private String byte2HexFormat(byte[] data,int width,
			IByte2String hexPartitionMethod,IByte2String strPartitionMethod) 
	{
		StringBuffer sb = new StringBuffer();
		//表头
		for(int i=0;i<width;i++) {
			sb.append("-");
			if(i<10) sb.append(i);
			else sb.append((char)(i-10+'a'));
			sb.append("-");
		}
		sb.append("\r\n");
		int index = 0;
		StringBuffer hexPartionLine = new StringBuffer();
		StringBuffer strPartionLine = new StringBuffer();
		while(index < data.length) {
			int lineStart = index; 
			while(index < data.length && index < lineStart+width) {
				hexPartionLine.append(hexPartitionMethod.byte2String(data[index]))
									.append(Configuration.DELIMITER);
				strPartionLine.append(strPartitionMethod.byte2String(data[index]));
				index ++;
			}
			int placeholderNum = 0;
			while(index+placeholderNum < lineStart+width) {//对最后一行不足width的在HexPartition部分补充占位符
				hexPartionLine.append("   ");
				placeholderNum += 1;
			}
			sb.append(hexPartionLine).append(Configuration.PARTITION)
								.append(strPartionLine).append("\r\n");//完成一行显示
			hexPartionLine.delete(0, hexPartionLine.length());
			strPartionLine.delete(0, strPartionLine.length());
		}
		return sb.toString();
	}
	
	public String b2HEX(byte[] data) {
		return byte2Hex(data, "", Configuration.byte2HexUpper);
	}
	
	public String b2HEX(byte[] data,String delimiter) {
		return byte2Hex(data, delimiter, Configuration.byte2HexUpper);
	}
	
	public String b2hex(byte[] data) {
		return byte2Hex(data, "", Configuration.byte2HexLower);
	}
	
	public String b2hex(byte[] data,String delimiter) {
		return byte2Hex(data, "", Configuration.byte2HexLower);
	}
	
	private String byte2Hex(byte[] data,String delimiter,IByte2String form) {
		StringBuffer sb = new StringBuffer();
		int index = 0;
		while(index < data.length) {
			sb.append(form.byte2String(data[index])).append(delimiter);
			index ++;
		}
		return sb.toString();
	}

	public byte[] hex2b(String hexStr) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		if(hexStr.length() % 2 != 0) {
			throw new IllegalArgumentException("输入参数"+hexStr+"长度不是偶数.");
		}
		int c = 0;
		while(c < hexStr.length()) {
			int high = Configuration.hexChar2Int(hexStr.charAt(c));
			int low = Configuration.hexChar2Int(hexStr.charAt(c+1));
			if(high == -1) {
				throw new IllegalArgumentException("输入参数"+hexStr+".charAt("+c+")="+hexStr.charAt(c)+"不是合法的HexChar");
			}
			if(low == -1) {
				throw new IllegalArgumentException("输入参数"+hexStr+".charAt("+(c+1)+")="+hexStr.charAt(c+1)+"不是合法的HexChar");
			}
			baos.write(Configuration.BCDPackedFormat(high,low));
			c += 2;
		}
		return baos.toByteArray();
	}
		
	private static class Configuration {
		static final char[] HEX_UPPER_CASE = new char[]{
			'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
		};
	
		static final char[] HEX_LOWER_CASE = new char[]{
			'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
		};
		
		/**
		 * @return -1 表示输入参数hexChar不是个合法的HexChar. 其他情况返回的数据控制在[0,15]
		 * */
		static int hexChar2Int(char hexChar) {
			if(Character.isDigit(hexChar)) return hexChar - '0';
			else if(Character.isLowerCase(hexChar)) return hexChar - 'a' + 10;
			else if(Character.isUpperCase(hexChar)) return hexChar - 'A' + 10;
			else return -1;
		}
		
		static byte BCDPackedFormat(int high,int lower) {
			int min = Math.min(high, lower);
			int max = Math.max(high, lower);
			if(min<0 || max >15) {
				throw new IllegalArgumentException("输入参数"+high+","+lower+"都必须控制在范围[0,15]内");
			}
			return (byte)(high << 4 | lower);
		}
		
		/** 各个Byte之间的分割符号*/
		static final String DELIMITER = " ";
		
		/** Hex显示和字符显示区域分割符*/
		static final String PARTITION = ";";
		
		static IByte2String byte2HexUpper;
		
		static IByte2String byte2HexLower;
		
		static IByte2String byte2ASCII;
		
		
	} 
	
	interface IByte2String {
		public String byte2String(byte b); 
	}
	
	class Byte2HexUpper implements IByte2String {
		public String byte2String(byte b) {
			int high = 0x0F & b>>4;
			int low  = 0x0F & b;
			return new String(new char[] {Configuration.HEX_UPPER_CASE[high],
								Configuration.HEX_UPPER_CASE[low]});
		}
	}
	
	class Byte2HexLower implements IByte2String {
		public String byte2String(byte b) {
			int high = 0x0F & b>>4;
			int low  = 0x0F & b;
			return new String(new char[] {Configuration.HEX_LOWER_CASE[high],
							Configuration.HEX_LOWER_CASE[low]});
		}
	}
	
	class Byte2ASCII implements IByte2String {
		private final String INVISIBLE_SUBSTITUTION = ".";
		
		public String byte2String(byte b) {
			return (Character.isWhitespace(b) || Character.isLetterOrDigit(b)) ? new String(new byte[]{b}) : INVISIBLE_SUBSTITUTION;
		}
	}
}