我有一个字节数组充满十六进制数字和打印它的简单方式是相当没有意义的,因为有许多不可打印的元素。我需要的是精确的十六进制形式:3a5f771c
当前回答
对于固定长度,我会使用这样的东西,比如哈希值:
md5sum = String.format("%032x", new BigInteger(1, md.digest()));
其他回答
只是迭代所有字节,转换为十六进制字符串使用整数。toString(不幸的是,没有字节。toString(带基数形参)并将它们全部附加到StringBuilder中。
byte[] arr;//set it to your value
StringBuilder sb=new StringBuilder(arr.length*2);//1 byte...2 hex digits
for(int i=0;i<arr.length;i++){
sb.append(Integer.toString(arr[i],16));
}
String hexValue=sb.toString();
这类似于指针Null的答案,但它使用整数。toString而不是String。格式提高性能。
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
我发现了三种不同的方法: http://www.rgagnon.com/javadetails/java-0596.html
他还提到,我认为最优雅的一个是:
static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
if ( raw == null ) {
return null;
}
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
Converts bytes data to hex characters
@param bytes byte array to be converted to hex string
@return byte String in hex format
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int v;
for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
这是一个java.util。类似base64的实现,是不是很漂亮?
import java.util.Arrays;
public class Base16/* a.k.a. Hex */ {
public static class Encoder{
private static char[] toLowerHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
private static char[] toUpperHex={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
private boolean upper;
public Encoder(boolean upper) {
this.upper=upper;
}
public String encode(byte[] data){
char[] value=new char[data.length*2];
char[] toHex=upper?toUpperHex:toLowerHex;
for(int i=0,j=0; i<data.length; i++){
int octet=data[i]&0xFF;
value[j++]=toHex[octet>>4];
value[j++]=toHex[octet&0xF];
}
return new String(value);
}
static final Encoder LOWER_CASE=new Encoder(false);
static final Encoder UPPER_CASE=new Encoder(true);
}
public static Encoder getEncoder(){
return Encoder.LOWER_CASE;
}
public static Encoder getUpperEncoder(){
return Encoder.UPPER_CASE;
}
public static class Decoder{
private static int maxIndex=102;
private static int[] toIndex;
static {
toIndex=new int[maxIndex+1];
Arrays.fill(toIndex, -1);
char[] chars={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'};
for(int i=0; i<chars.length; i++) {
toIndex[(int)chars[i]]=i;
}
}
public Decoder() {
}
public byte[] decode(String str) {
char[] value=str.toCharArray();
int start=0;
if(value.length>2 && value[0]=='0' && (value[1]=='x' || value[1]=='X')) {
start=2;
}
int byteLength=(value.length-start)/2; // ignore trailing odd char if exists
byte[] data=new byte[byteLength];
for(int i=start,j=0;i<value.length;i+=2,j++){
int i1;
int i2;
char c1=value[i];
char c2=value[i+1];
if(c1>maxIndex || (i1=toIndex[(int)c1])<0 || c2>maxIndex || (i2=toIndex[(int)c2])<0) {
throw new IllegalArgumentException("Invalid character at "+i);
}
data[j]=(byte)((i1<<4)+i2);
}
return data;
}
static final Decoder IGNORE_CASE=new Decoder();
}
public static Decoder getDecoder(){
return Decoder.IGNORE_CASE;
}
}
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap