java中byte数组与十六进制字符串相互转换

最近在做加密算法的研究和使用,经常会用到byte数组和十六进制字符串的转换。之前对于此类问题我一般都是使用BigInteger这个类转换一下算了,这样为了看输出不是乱码。这其实都不是根本上的解决方案。

最简单的转换方法:

/**
 * @see 将byte[]数组转换为String字符串
 * @author Herman.Xiong
 * @date 2014年5月5日 17:15:42
 * @param data byte数组
 * @return String 转换后的字符串
 */
public static String byteToArray(byte[]data){
	String result="";
	for (int i = 0; i < data.length; i++) {
		result+=Integer.toHexString((data[i] & 0xFF) | 0x100).toUpperCase().substring(1, 3);
	}
	return result;
}

我们看看java的byte[]数组的原理:

Java中byte用二进制表示占用8位,而我们知道16进制的每个字符需要用4位二进制位来表示。

所以我们就可以把每个byte转换成两个相应的16进制字符,即把byte的高4位和低4位分别转换成相应的16进制字符H和L,并组合起来得到byte转换到16进制字符串的结果new String(H) + new String(L)。

同理,相反的转换也是将两个16进制字符转换成一个byte,原理同上。

根据以上原理,我们就可以将byte[] 数组转换为16进制字符串了,当然也可以将16进制字符串转换为byte[]数组了。

一下是代码工具类:

package com.herman.test;

/**
 * @see byte数组与十六进制字符串互转
 * @author Herman.Xiong
 * @date 2014年5月5日 17:00:01
 */
public class Hex {

	/**
	 * 用于建立十六进制字符的输出的小写字符数组
	 */
	private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	/**
	 * 用于建立十六进制字符的输出的大写字符数组
	 */
	private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

	/**
	 * @see 将字节数组转换为十六进制字符数组
	 * @author Herman.Xiong
	 * @date 2014年5月5日 17:06:52
	 * @param data byte[]
	 * @return 十六进制char[]
	 */
	public static char[] encodeHex(byte[] data) {
		return encodeHex(data, true);
	}

	/**
	 * @see 将字节数组转换为十六进制字符数组
	 * @author Herman.Xiong
	 * @date 2014年5月5日 17:07:14
	 * @param data byte[]
	 * @param toLowerCase true传换成小写格式 ,false传换成大写格式
	 * @return 十六进制char[]
	 */
	public static char[] encodeHex(byte[] data, boolean toLowerCase) {
		return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
	}

	/**
	 * @see 将字节数组转换为十六进制字符数组
	 * @author Herman.Xiong
	 * @date 2014年5月5日 17:07:31
	 * @param data byte[]
	 * @param toDigits 用于控制输出的char[]
	 * @return 十六进制char[]
	 */
	protected static char[] encodeHex(byte[] data, char[] toDigits) {
		int l = data.length;
		char[] out = new char[l << 1];
		for (int i = 0, j = 0; i < l; i++) {
			out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
			out[j++] = toDigits[0x0F & data[i]];
		}
		return out;
	}

	/**
	 * @see 将字节数组转换为十六进制字符串
	 * @date 2014年5月5日 17:07:43
	 * @author Herman.Xiong
	 * @param data byte[]
	 * @return 十六进制String
	 */
	public static String encodeHexStr(byte[] data) {
		return encodeHexStr(data, true);
	}

	/**
	 * @see 将字节数组转换为十六进制字符串
	 * @author Herman.Xiong
	 * @date 2014年5月5日 17:08:01
	 * @param data byte[]
	 * @param toLowerCase true 传换成小写格式 , false 传换成大写格式
	 * @return 十六进制String
	 */
	public static String encodeHexStr(byte[] data, boolean toLowerCase) {
		return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
	}

	/**
	 * @see 将字节数组转换为十六进制字符串
	 * @author Herman.Xiong
	 * @date 2014年5月5日 17:08:15
	 * @param data byte[]
	 * @param toDigits 用于控制输出的char[]
	 * @return 十六进制String
	 */
	protected static String encodeHexStr(byte[] data, char[] toDigits) {
		return new String(encodeHex(data, toDigits));
	}

	/**
	 * @see 将十六进制字符数组转换为字节数组
	 * @author Herman.Xiong
	 * @date 2014年5月5日 17:08:28
	 * @param data 十六进制char[]
	 * @return byte[]
	 * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
	 */
	public static byte[] decodeHex(char[] data) {
		int len = data.length;
		if ((len & 0x01) != 0) {
			throw new RuntimeException("未知的字符");
		}
		byte[] out = new byte[len >> 1];
		for (int i = 0, j = 0; j < len; i++) {
			int f = toDigit(data[j], j) << 4;
			j++;
			f = f | toDigit(data[j], j);
			j++;
			out[i] = (byte) (f & 0xFF);
		}
		return out;
	}

	/**
	 * @see 将十六进制字符转换成一个整数
	 * @author Herman.Xiong
	 * @date 2014年5月5日 17:08:46
	 * @param ch  十六进制char
	 * @param index 十六进制字符在字符数组中的位置
	 * @return 一个整数
	 * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
	 */
	protected static int toDigit(char ch, int index) {
		int digit = Character.digit(ch, 16);
		if (digit == -1) {
			throw new RuntimeException("非法16进制字符 " + ch
					+ " 在索引 " + index);
		}
		return digit;
	}

	/**
	 * @see 将byte[]数组转换为String字符串
	 * @author Herman.Xiong
	 * @date 2014年5月5日 17:15:42
	 * @param data byte数组
	 * @return String 转换后的字符串
	 */
	public static String byteToArray(byte[]data){
		String result="";
		for (int i = 0; i < data.length; i++) {
			result+=Integer.toHexString((data[i] & 0xFF) | 0x100).toUpperCase().substring(1, 3);
		}
		return result;
	}

	public static void main(String[] args) {
		String srcStr = "待转换字符串";
		String encodeStr = encodeHexStr(srcStr.getBytes());
		String decodeStr = new String(decodeHex(encodeStr.toCharArray()));
		System.out.println("转换前:" + srcStr);
		System.out.println("转换后:" + encodeStr);
		System.out.println("还原后:" + decodeStr);
	}

}

运行后效果:

时间: 2024-09-10 02:46:59

java中byte数组与十六进制字符串相互转换的相关文章

字符-java 中byte数组转换问题,求思路

问题描述 java 中byte数组转换问题,求思路 现在做的项目有一个byte数组转换的问题,思考很久没有思路,求各路大神给点意见. 需求 :将一个byte数组中的每个元素拆分成两个byte.分别保存前一个byte中的16进制两位的内容的ascii码. 事例 : byte[] a = {0x24,0xBD}; byte[] b = new byte[4]; 想得到的结果: b[0] == 0x32; b[1] == 0x34; b[2] == 0x42; b[3] == 0x44;

基于java中byte数组与int类型的转换(两种方法)_java

java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法,我们都知道,在socket传输中,发送.者接收的数据都是 byte数组,但是int类型是4个byte组成的,如何把一个整形int转换成byte数组,同时如何把一个长度为4的byte数组转换为int类型.下面有两种方式. public static byte[] int2byte(int res) { byte[] targets = new byte[4]; targets[0] = (byte) (res & 0xf

Java中char数组(字符数组)与字符串String类型的转换方法_java

本文实例讲述了Java中char数组(字符数组)与字符串String类型的转换方法.分享给大家供大家参考,具体如下: 在Java语言编程时,使用"口令字段"jPasswordField组件时,如果要获得密码值,就需要使用该组件的getPassword()方法.jPasswordField的getPassword()方法返回一个char类型的数组,我们经常需要将这个数组转换为String类型,以便进行诸如口令匹配或口令赋值等操作.这时,就需要将char类型的数组进行转换.当然也经常会遇到

详解Java中的数组与字符串相关知识_java

Java数组的定义和使用 如果希望保存一组有相同类型的数据,可以使用数组. 数组的定义和内存分配 Java 中定义数组的语法有两种: type arrayName[]; type[] arrayName; type 为Java中的任意数据类型,包括基本类型和组合类型,arrayName为数组名,必须是一个合法的标识符,[ ] 指明该变量是一个数组类型变量.例如: int demoArray[]; int[] demoArray; 这两种形式没有区别,使用效果完全一样,读者可根据自己的编程习惯选择

c#与java中byte字节的区别及转换方法

原文:c#与java中byte字节的区别及转换方法在java中  byte的范围在 [-128,127] 在C#中  byte的范围在 [0,255] 所以 java程序与C#程序 进行数据传输的时候 要先把java的byte数组转换成在[0,255]范围内的int型数组a[];再把a[]进行加密得到字符串str, 把字符串传到web服务上. 转换方法: int data[] = new int[bytes.length]; for(int i=0;i    data[i] = bytes[i]

js接收并转化Java中的数组对象的方法_javascript技巧

在做项目时,要向ocx控件下发命令,就要在js中得到java中的对象,然后拼成一种格式,下发下去...当对象是一个时比较简单,但如果对象是一个数组时,就略显麻烦了. 开始我以为有简单的方式,可以直接进行内容的转化,后来发现不可以,网上说js与java没有桥接的东西,所以呢: 我的解决方案是:在action层,将java的对象数组转化为Json串,而在js中,再把json转化为数组对象. 1.将java的对象数组转化为Json串: 要用到两个类: net.sf.json.JSONObject ne

Arrays类应用&amp;#183;使用Arrays类操作Java中的数组

使用 Arrays 类操作 Java 中的数组 Arrays 类是 Java 中提供的一个工具类,在 java.util 包中.该类中包含了一些方法用来直接操作数组,比如可直接实现数组的排序.搜索等(关于类和方法的相关内容在后面的章节中会详细讲解滴~~). Arrays 中常用的方法: 1. 排序 语法:  Arrays.sort(数组名); 可以使用 sort( ) 方法实现对数组的排序,只要将数组名放在 sort( ) 方法的括号中,就可以完成对该数组的排序(按升序排列),如: 运行结果: 

* java 中的数组 对象数组 以及main方法中的参数 x y不用中间参数实现交换

 /*  java 中的数组  对象数组   以及main方法中的参数    x y不用中间参数实现交换java 基本数据类型 的数组 初始化元素为 0java中数组名.length表示数组中元素的个数 main方法中的 args[] 从0开始 是java 类  后面的字符串  args.length也是保存了 元素的个数 System.out.println()  在打印对象的时候 包括我们自己定义的对象 他会调用toString方法 因为所有类都是从object派生而来  打印出类测描述建议

java中String数组问题,String[3][2]是表示有6个对象吗?

问题描述 java中String数组问题,String[3][2]是表示有6个对象吗? String[ ][ ] zhuangtai=new String[3][2]; 是表示有6种不同的状态吗,如何理解呢?新手提问,莫见笑 解决方案 上面的错了,应该都是从00开始 这是一个二维数字,里面可以存储6个属性 分别为[0][0] [0][1] [1][0] [1][1] [2][0] [2][1] 你可以看下我这篇文章http://blog.csdn.net/zhanggang740/article