我正在使用“Blowfish”算法来加密和解密文本内容。我将加密的内容嵌入到图像中但是在提取时我得到的是字节数组,我将它传递给类 Cipher 的方法更新。
但是该方法返回了我想要转换回人类可读形式的字节数组
当我使用 FileOutputStream 的编写方法时,在提供文件名时工作正常。
但现在我想以人类可读的格式在控制台上打印它。如何通过这个?我也尝试过ByteArrayOutputStream。但效果不佳。
谢谢。
答案 0 :(得分:7)
如果您只想查看数值,则可以遍历数组并打印每个字节:
for(byte foo : arr){
System.out.print(foo + " ");
}
或者,如果您想查看十六进制值,可以使用printf
:
System.out.printf("%02x ", foo);
如果要查看字节数组所代表的字符串,可以执行
System.out.print(new String(arr));
答案 1 :(得分: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();
}
}
答案 2 :(得分:5)
byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46};
String value = new String(byteArray);
答案 3 :(得分:3)
byte[] data = new byte[] {1, 2, 3, 4};
System.out.printf( Arrays.toString( data ) );
[1, 2, 3, 4]
答案 4 :(得分:0)
最好做一个十六进制字节数组
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();
}
答案 5 :(得分:0)
这不是很多人认为的琐碎的任务。每个字节的值范围从-128到127。其中大多数是不可打印的字符。
为了以人类可读的格式编码字节,您应该了解只有62个字母数字字符。 ONE BYTE不可能映射到一个人类可读的字符,因为可能的字节数超过了人类可以轻松读取的62个字符。
Bellow是我编写的一个类,该类使用提供的字母将字节数组转换为String(如果没有提供,则默认为字符串)。
从1到7个输入字节的块中进行转换。不能使用超过7个字节,因为它是最大Java long值的最大值。而且我在进行转换时会使用长值。
如果例如大小为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));
}
}