Skip to content

Instantly share code, notes, and snippets.

@zhoulifu
Created April 28, 2017 07:42
Show Gist options
  • Save zhoulifu/31069973d775a99e9a50c1ea89649b5a to your computer and use it in GitHub Desktop.
Save zhoulifu/31069973d775a99e9a50c1ea89649b5a to your computer and use it in GitHub Desktop.
Hexdump forked from org.apache.commons.io.HexDump
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Objects;
public class Hexdump {
/**
* width after an integer was translated into hexadecimal
*/
private static final int INT_W = 8;
/**
* width after a byte was translated into hexadecimal
*/
private static final int BYTE_W = 2;
/**
* organized into rows of 16 bytes
*/
private static final int GROUP_SIZE = 16;
/**
* bytes per row
*/
private static final int ROW_SIZE = 76;
private static final String EOL = System.getProperty("line.separator");
private static final char[] HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static final int[] shifts = {28, 24, 20, 16, 12, 8, 4, 0};
/**
* Dump an array of bytes to an OutputStream.
* @param bytes bytes to be dumped
* @param offset the offset in the bytes of the first byte to dump
* @param length the maximum number of bytes to dump
* @param out the output stream to which data is to be written
* @throws IOException
*/
public static void dump(
byte[] bytes, int offset, int length, OutputStream out) throws IOException {
dump(new ByteArrayInputStream(bytes, offset, length), out);
}
/**
* Dump an array of bytes to an OutputStream.
* @param bytes bytes to be dumped
* @param out the output stream to which data is to be written
* @throws IOException
*/
public static void dump(byte[] bytes, OutputStream out) throws IOException {
dump(new ByteArrayInputStream(bytes), out);
}
/**
*
* @param bytes bytes to be dumped
* @param offset the offset in the bytes of the first byte to dump
* @param length the maximum number of bytes to dump
* @return the dump result in string representation
*/
public static String dumpIntoString(byte[] bytes, int offset, int length) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
dump(bytes, offset, length, out);
return out.toString();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
/**
*
* @param bytes bytes to be dumped
* @return the dump result in string representation
*/
public static String dumpIntoString(byte[] bytes) {
return dumpIntoString(bytes, 0, bytes.length);
}
/**
* Dump the content of the given InputStream to an OutputStream.
* @param in the input stream to be dumped
* @param out the output stream to which data is to be written
* @throws IOException
*/
public static void dump(InputStream in, OutputStream out) throws IOException {
Objects.requireNonNull(in, "input");
Objects.requireNonNull(out, "output");
byte[] buffer = new byte[GROUP_SIZE];
StringBuilder sb = new StringBuilder(ROW_SIZE);
int read;
int offset = 0;
while ((read = in.read(buffer)) != -1) {
// Dump read offset
dump(sb, offset, INT_W);
sb.append(" ");
// Hex dump
for (int i = 0; i < GROUP_SIZE; i++) {
if (i < read) {
dump(sb, buffer[i], BYTE_W);
} else {
sb.append(" ");
}
sb.append(i == 7 ? " " : ' ');
}
sb.append(' ');
// Ascii texts
for (int i = 0; i < read; i++) {
byte b = buffer[i];
if (b >= ' ' && b < 127) {
sb.append(((char) b));
} else {
sb.append('.');
}
}
sb.append(EOL);
out.write(sb.toString().getBytes());
sb.setLength(0);
offset += read;
}
// Checksum
dump(sb, offset, INT_W);
out.write(sb.toString().getBytes());
out.flush();
}
private static void dump(StringBuilder sb, int value, int width) {
for (int i = 0; i < width; i++) {
sb.append(HEX_CHARS[(value >>> shifts[8 - width + i]) & 0x0F]);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment