Java 如何将字节数组转换为人类可读的格式?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4141317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert byte array into Human readable format?
提问by Supereme
I am using "Blowfish" algorithm to encrypt and decrypt the contents of the text. I am embedding the encrypted contents in the image but while extracting I am getting the byte array which I am passing it to method updateof class Cipher.
我正在使用“Blowfish”算法来加密和解密文本内容。我将加密的内容嵌入到图像中,但是在提取时我得到了字节数组,我将它传递给类Cipher 的方法更新。
But the method returns me byte array which I want to convert back into Human readable form.
When I use writemethod of FileOutputStreamit is working fine when a filename is provided.
But now I want to print it on the console in the human readable format. How to get through this? I have tried for ByteArrayOutputStream too. But didn't work well.
但是该方法返回给我的字节数组,我想将其转换回人类可读的形式。
当我使用FileOutputStream 的write方法时,它在提供文件名时工作正常。
但现在我想以人类可读的格式在控制台上打印它。如何度过这一关?我也尝试过 ByteArrayOutputStream。但效果并不好。
Thank you.
谢谢你。
采纳答案by Barun
byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46};
String value = new String(byteArray);
回答by Mark Elliot
If all you want to do is see the numeric values you can loop through the array and print each byte:
如果您只想查看数值,您可以遍历数组并打印每个字节:
for(byte foo : arr){
System.out.print(foo + " ");
}
Or if you want to see hex values you can use printf
:
或者,如果您想查看十六进制值,可以使用printf
:
System.out.printf("%02x ", foo);
If you want to see the string that the byte array represents you can just do
如果您想查看字节数组表示的字符串,您可以这样做
System.out.print(new String(arr));
回答by Nikolaus Gradwohl
You can convert the bytearray into a string containing the hex values of the bytes using this method. This even works on java < 6
您可以使用此方法将 bytearray 转换为包含字节十六进制值的字符串。这甚至适用于 java < 6
public class DumpUtil {
private static final String HEX_DIGITS = "0123456789abcdef";
public static String toHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i != data.length; i++) {
int v = data[i] & 0xff;
buf.append(HEX_DIGITS.charAt(v >> 4));
buf.append(HEX_DIGITS.charAt(v & 0xf));
buf.append(" ");
}
return buf.toString();
}
}
回答by Tag
byte[] data = new byte[] {1, 2, 3, 4};
System.out.printf( Arrays.toString( data ) );
[1, 2, 3, 4]
回答by secmask
It's better to do a hexDump that byte array
最好做一个 hexDump 那个字节数组
private static final byte[] HEX_CHAR = new byte[] { '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
public static final String dumpBytes(byte[] buffer) {
if (buffer == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.setLength(0);
for (int i = 0; i < buffer.length; i++) {
sb.append((char) (HEX_CHAR[(buffer[i] & 0x00F0) >> 4]))
.append((char) (HEX_CHAR[buffer[i] & 0x000F])).append(' ');
}
return sb.toString();
}
回答by Stan Sokolov
It is not a trivial task, as many people assume. Each byte has values ranging from -128 to 127. Most of them are non printable characters.
正如许多人所认为的那样,这不是一项微不足道的任务。每个字节的值范围从 -128 到 127。它们中的大多数是不可打印的字符。
In order to encode bytes in a human readable format you should understand that there is only 62 alphanumeric characters. There is no way ONE BYTE will map to ONE human readable characters as there is more possible bytes than 62 characters human can easily read.
为了以人类可读的格式对字节进行编码,您应该了解只有 62 个字母数字字符。一个字节不可能映射到一个人类可读的字符,因为可能的字节多于人类可以轻松读取的 62 个字符。
Bellow is a class I wrote that converts a byte array into a String using provided alphabet (or a default if none provided).
Bellow 是我编写的一个类,它使用提供的字母表(如果没有提供,则为默认值)将字节数组转换为字符串。
It does conversion in chunks from 1 to 7 input bytes. Could not use more than 7 bytes is it is max for the biggest Java long value. And I use long values when do conversion.
它从 1 到 7 个输入字节的块中进行转换。不能使用超过 7 个字节,这是最大 Java 长值的最大值。我在转换时使用长值。
If chunk for example of size 5 than it needs 7 alphanumeric symbols to encode a chunk of 5 bytes. So size of output will be greater than size of input.
如果块例如大小为 5,则需要 7 个字母数字符号来编码 5 个字节的块。所以输出的大小将大于输入的大小。
import org.slf4j.Logger;
/**************************************************************************************************************
* Convert bytes into human readable string using provided alphabet.
* If alphabet size 62 chars and byte chunk is 5 bytes then we need 7 symbols to encode it.
* So input size will be increased by 40% plus 7 symbols to encode length of input
*
* Basically we do conversion from base255 (byte can has 255 different symbols) to base of a a size of the
* given alphabet
*
* @author Stan Sokolov
* 10/9/19
**************************************************************************************************************/
public class HumanByte {
final static private Logger logger = org.slf4j.LoggerFactory.getLogger(OsmRouting.class);
// those are chars we use for encoding
private final static String DEFAULT_ALPHABET = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
private char[] ALPHABET;
private int BASE;
private int[] POSITIONS;
private int CHUNK;
private int PW;
private long[] POWERS; // {916132832, 14776336, 238328, 3844, 62, 1};
private long[] MASKS; //(0xFF000000L & (input[0] << 24)) | (0xFF0000L & input[1] << 16) | (0xFF00L & input[2] << 8) | (0xFFL & input[3]);
/**************************************************************************************************************
* Default constructor, with default alphabet and default chunk
**************************************************************************************************************/
public HumanByte() {
this(DEFAULT_ALPHABET, 5);
}
/**************************************************************************************************************
* Setup encoding using provided alphabet and chunk size
**************************************************************************************************************/
public HumanByte(final String alphabet, int chunk) {
if (chunk>7){
chunk=7;
}
if (chunk<1){
chunk=1;
}
this.ALPHABET = alphabet.toCharArray();
BASE = alphabet.length();
CHUNK = chunk;
long MX = (long) Math.pow(255, CHUNK);
PW = logBase(MX);
int max=0;
for (int i = 0; i < ALPHABET.length; i++) {
if (max<ALPHABET[i]) max=ALPHABET[i];
}
POSITIONS = new int[max+1];
logger.debug("BASE={}, MX={}, PW={}", BASE, MX, PW);
for (int i = 0; i < ALPHABET.length; i++) {
POSITIONS[ALPHABET[i]] = i;
}
POWERS = new long[PW]; //these are the powers of base to split input number into digits of its base
for (int i = 0; i < PW; i++) {
POWERS[i] = (long) Math.pow(BASE, PW - i - 1);
}
MASKS = new long[CHUNK];
for (int i = 0; i < CHUNK; i++) { //this is how we are going to extract individual bytes from chunk
MASKS[i] = (0xFFL << ((CHUNK - i - 1) * 8));
}
}
/**************************************************************************************************************
* take bytes, split them in group by CHUNK, encode each group in PW number of alphabet symbols.
**************************************************************************************************************/
public String encode(final byte[] input) {
final StringBuilder output = new StringBuilder(); //will save output string here
output.append(word(input.length)); // first write length of input into output to know exact size
byte[] byte_word;
for (int i = 0; i < input.length; ) {
byte_word = new byte[CHUNK];
for (int j = 0; j < CHUNK; j++) {
if (i < input.length) {
byte_word[j] = input[i++]; //remove negatives
}
}
final long n = bytes2long(byte_word); //1099659687880
final char[] w = word(n);
output.append(w);
}
return output.toString();
}
/**************************************************************************************************************
* decode input
**************************************************************************************************************/
public byte[] decode(final String in) {
final int size = (int) number(in.substring(0, PW).toCharArray());
final byte[] output = new byte[size];
int j = 0, k = in.length();
for (int i = PW; i < k; i += PW) {
final String w = in.substring(i, i + PW);
final long n = number(w.toCharArray());
for (byte b : long2bytes(n)) {
if (j < size) {
output[j++] = b;
}
}
}
return output;
}
/**************************************************************************************************************
* @return take 4 numbers from 0 to 255 and convert them in long
**************************************************************************************************************/
private long bytes2long(byte[] input) {
long v = 0;
for (int i = 0; i < CHUNK; i++) {
v |= ((long) (input[i]+ 128) << (8 * (CHUNK - i - 1)) & MASKS[i]); //+128 to remove negatives
}
return v;
}
/**************************************************************************************************************
* @return take 4 numbers from 0 to 255 and convert them in long
**************************************************************************************************************/
private byte[] long2bytes(long input) {
final byte[] bytes = new byte[CHUNK];
for (int i = 0; i < CHUNK; i++) {
long x = MASKS[i] & input;
long y = 8 * (CHUNK - i - 1);
long z = (x >> y) - 128;
bytes[i] = (byte) z;
}
return bytes;
}
/**************************************************************************************************************
* create word using given alphabet to represent given number built out of CHUNK bytes
**************************************************************************************************************/
private char[] word(final long n) {
final char[] output = new char[PW];
long v=n;
for (int i = 0; i < PW; i++) {
final long pn = v / POWERS[i];
output[i] = ALPHABET[(int) pn];
long x = pn * POWERS[i];//900798402816 196327857024 2368963584 16134768 267696 1716 52
v -= x;
}
return output;
}
/**************************************************************************************************************
* take string that contain number encoded in alphabet and return
**************************************************************************************************************/
private long number(final char[] s) {
long number = 0;
for (int i = 0; i < PW; i++) {
long x = (long) POSITIONS[s[i]];
long y = POWERS[i];
long z = x*y;
number += z;
}
return number;
}
private int logBase(long num) {
return (int) Math.ceil(Math.log(num) / Math.log(BASE));
}
}