All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xqbase.util.Bytes Maven / Gradle / Ivy

There is a newer version: 0.2.18
Show newest version
package com.xqbase.util;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.security.SecureRandom;
import java.util.Random;

/**
 * Variety of byte[] operations, including:
 * 
    *
  • Encoding/Decoding to/from hexadecimal
  • *
  • Storing/Retrieving short, int or long to/from byte[]
  • *
  • Concatenating/Truncating/Comparing of byte[]s *
  • Generating random byte[]
  • *
  • Dumping for debug
  • *
*/ public class Bytes { /** Not Little-Ending, i.e. storing/retrieving numbers in Big-Ending (default) byte order */ public static final boolean BIG_ENDIAN = false; /** Little-Ending, i.e. storing/retrieving numbers in Little-Ending byte order */ public static final boolean LITTLE_ENDIAN = true; /** A byte array with length of 0 */ public static final byte[] EMPTY_BYTES = {}; private static final char[] HEX_UPPER_CHAR = "0123456789ABCDEF".toCharArray(); private static final char[] HEX_LOWER_CHAR = "0123456789abcdef".toCharArray(); private static final byte[] HEX_DECODE_CHAR = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /** Decode from hexadecimal */ public static byte[] fromHex(String hex) { char[] c = hex.toCharArray(); byte[] b = new byte[c.length / 2]; for (int i = 0; i < b.length; i ++) { b[i] = (byte) (HEX_DECODE_CHAR[c[i * 2] & 0xFF] * 16 + HEX_DECODE_CHAR[c[i * 2 + 1] & 0xFF]); } return b; } private static String toHex(byte[] b, int off, int len, char[] hexChar) { char[] c = new char[len * 2]; for (int i = 0; i < len; i ++) { int n = b[off + i]; c[i * 2] = hexChar[(n & 0xF0) >>> 4]; c[i * 2 + 1] = hexChar[n & 0xF]; } return new String(c); } /** Encode to uppercase hexadecimal */ public static String toHexUpper(byte[] b) { return toHexUpper(b, 0, b.length); } /** Encode to uppercase hexadecimal */ public static String toHexUpper(byte[] b, int off, int len) { return toHex(b, off, len, HEX_UPPER_CHAR); } /** Encode to lowercase hexadecimal */ public static String toHexLower(byte[] b) { return toHexLower(b, 0, b.length); } /** Encode to lowercase hexadecimal */ public static String toHexLower(byte[] b, int off, int len) { return toHex(b, off, len, HEX_LOWER_CHAR); } /** Generate a 2-byte array from a short number in Big-Endian byte order */ public static byte[] fromShort(int n) { return fromShort(n, BIG_ENDIAN); } /** Generate a 2-byte array from a short number in a given byte order */ public static byte[] fromShort(int n, boolean littleEndian) { byte[] b = new byte[2]; setShort(n, b, 0, littleEndian); return b; } /** Store a short number into a byte array in Big-Endian byte order */ public static void setShort(int n, byte[] b, int off) { setShort(n, b, off, BIG_ENDIAN); } /** Store a short number into a byte array in a given byte order */ public static void setShort(int n, byte[] b, int off, boolean littleEndian) { if (littleEndian) { b[off] = (byte) n; b[off + 1] = (byte) (n >>> 8); } else { b[off] = (byte) (n >>> 8); b[off + 1] = (byte) n; } } /** Generate a 4-byte array from an int number in Big-Endian byte order */ public static byte[] fromInt(int n) { return fromInt(n, BIG_ENDIAN); } /** Generate a 4-byte array from an int number in a given byte order */ public static byte[] fromInt(int n, boolean littleEndian) { byte[] b = new byte[4]; setInt(n, b, 0, littleEndian); return b; } /** Store an int number into a byte array in Big-Endian byte order */ public static void setInt(int n, byte[] b, int off) { setInt(n, b, off, BIG_ENDIAN); } /** Store an int number into a byte array in a given byte order */ public static void setInt(int n, byte[] b, int off, boolean littleEndian) { if (littleEndian) { b[off] = (byte) n; b[off + 1] = (byte) (n >>> 8); b[off + 2] = (byte) (n >>> 16); b[off + 3] = (byte) (n >>> 24); } else { b[off] = (byte) (n >>> 24); b[off + 1] = (byte) (n >>> 16); b[off + 2] = (byte) (n >>> 8); b[off + 3] = (byte) n; } } /** Generate an 8-byte array from a long number in Big-Endian byte order */ public static byte[] fromLong(long n) { return fromLong(n, BIG_ENDIAN); } /** Generate an 8-byte array from a long number in a given byte order */ public static byte[] fromLong(long n, boolean littleEndian) { byte[] b = new byte[8]; setLong(n, b, 0, littleEndian); return b; } /** Store a long number into a byte array in Big-Endian byte order */ public static void setLong(long n, byte[] b, int off) { setLong(n, b, off, BIG_ENDIAN); } /** Store a long number into a byte array in a given byte order */ public static void setLong(long n, byte[] b, int off, boolean littleEndian) { if (littleEndian) { setInt((int) n, b, off, LITTLE_ENDIAN); setInt((int) (n >>> 32), b, off + 4, LITTLE_ENDIAN); } else { setInt((int) (n >>> 32), b, off, BIG_ENDIAN); setInt((int) n, b, off + 4, BIG_ENDIAN); } } /** Retrieve a short from a byte array in Big-Endian byte order */ public static int toShort(byte[] b) { return toShort(b, 0); } /** Retrieve a short from a byte array in a given byte order */ public static int toShort(byte[] b, boolean littleEndian) { return toShort(b, 0, littleEndian); } /** Retrieve a short from a byte array in Big-Endian byte order */ public static int toShort(byte[] b, int off) { return toShort(b, off, BIG_ENDIAN); } /** Retrieve a short from a byte array in a given byte order */ public static int toShort(byte[] b, int off, boolean littleEndian) { if (littleEndian) { return ((b[off] & 0xFF) | ((b[off + 1] & 0xFF) << 8)); } return (((b[off] & 0xFF) << 8) | (b[off + 1] & 0xFF)); } /** Retrieve an int from a byte array in Big-Endian byte order */ public static int toInt(byte[] b) { return toInt(b, 0); } /** Retrieve an int from a byte array in a given byte order */ public static int toInt(byte[] b, boolean littleEndian) { return toInt(b, 0, littleEndian); } /** Retrieve an int from a byte array in Big-Endian byte order */ public static int toInt(byte[] b, int off) { return toInt(b, off, BIG_ENDIAN); } /** Retrieve an int from a byte array in a given byte order */ public static int toInt(byte[] b, int off, boolean littleEndian) { if (littleEndian) { return (b[off] & 0xFF) | ((b[off + 1] & 0xFF) << 8) | ((b[off + 2] & 0xFF) << 16) | ((b[off + 3] & 0xFF) << 24); } return ((b[off] & 0xFF) << 24) | ((b[off + 1] & 0xFF) << 16) | ((b[off + 2] & 0xFF) << 8) | (b[off + 3] & 0xFF); } /** Retrieve a long from a byte array in Big-Endian byte order */ public static long toLong(byte[] b) { return toLong(b, 0); } /** Retrieve a long from a byte array in a given byte order */ public static long toLong(byte[] b, boolean littleEndian) { return toLong(b, 0, littleEndian); } /** Retrieve a long from a byte array in Big-Endian byte order */ public static long toLong(byte[] b, int off) { return toLong(b, off, BIG_ENDIAN); } /** Retrieve a long from a byte array in a given byte order */ public static long toLong(byte[] b, int off, boolean littleEndian) { if (littleEndian) { return (toInt(b, off, LITTLE_ENDIAN) & 0xFFFFFFFFL) | ((toInt(b, off + 4, LITTLE_ENDIAN) & 0xFFFFFFFFL) << 32); } return ((toInt(b, off, BIG_ENDIAN) & 0xFFFFFFFFL) << 32) | (toInt(b, off + 4, BIG_ENDIAN) & 0xFFFFFFFFL); } /** Concatenate 2 byte arrays */ public static byte[] add(byte[] b1, int off1, int len1, byte[] b2, int off2, int len2) { byte[] b = new byte[len1 + len2]; System.arraycopy(b1, off1, b, 0, len1); System.arraycopy(b2, off2, b, len1, len2); return b; } /** Concatenate n byte arrays */ public static byte[] add(byte[]... b) { int nLen = 0; for (int i = 0; i < b.length; i ++) { nLen += b[i].length; } byte[] lp = new byte[nLen]; nLen = 0; for (int i = 0; i < b.length; i ++) { byte[] lpi = b[i]; System.arraycopy(lpi, 0, lp, nLen, lpi.length); nLen += lpi.length; } return lp; } /** Clone a byte array */ public static byte[] clone(byte[] b) { return sub(b, 0, b.length); } /** Truncate and keep left part of a byte array */ public static byte[] left(byte[] b, int len) { return sub(b, 0, len); } /** Truncate and keep right part of a byte array (by a given length) */ public static byte[] right(byte[] b, int len) { return sub(b, b.length - len, len); } /** Truncate and keep right part of a byte array (by a given position) */ public static byte[] sub(byte[] b, int off) { return sub(b, off, b.length - off); } /** Truncate and keep middle part of a byte array */ public static byte[] sub(byte[] b, int off, int len) { byte[] result = new byte[len]; System.arraycopy(b, off, result, 0, len); return result; } /** Check whether a byte array equals to another */ public static boolean equals(byte[] b1, int off1, byte[] b2, int off2, int len) { if (b1 == b2 && off1 == off2) { return true; } for (int i = 0; i < len; i ++) { if (b1[off1 + i] != b2[off2 + i]) { return false; } } return true; } /** Check whether a byte array equals to another */ public static boolean equals(byte[] b1, byte[] b2) { return b1.length == b2.length && equals(b1, 0, b2, 0, b1.length); } private static Random random = new Random(); private static SecureRandom secureRandom = new SecureRandom(); private static byte[] random(int len, Random random_) { byte[] result = new byte[len]; random_.nextBytes(result); return result; } /** Generate a random byte array by a given length */ public static byte[] random(int len) { return random(len, random); } /** Generate a random byte array by a given length, using secure random number generator */ public static byte[] secureRandom(int len) { return random(len, secureRandom); } private static String dumpLine(byte[] b, int offDiv16, int begin, int end) { char[] line = " ".toCharArray(); // "0000:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................" line[0] = HEX_UPPER_CHAR[(offDiv16 >>> 24) & 0xF]; line[1] = HEX_UPPER_CHAR[(offDiv16 >>> 20) & 0xF]; line[2] = HEX_UPPER_CHAR[(offDiv16 >>> 16) & 0xF]; line[3] = HEX_UPPER_CHAR[(offDiv16 >>> 12) & 0xF]; line[4] = ':'; line[5] = HEX_UPPER_CHAR[(offDiv16 >>> 8) & 0xF]; line[6] = HEX_UPPER_CHAR[(offDiv16 >>> 4) & 0xF]; line[7] = HEX_UPPER_CHAR[offDiv16 & 0xF]; line[8] = '0'; for (int i = 0; i < 16; i ++) { if (i >= begin && i < end) { int b_ = b[offDiv16 * 16 + i]; line[i * 3 + 11] = HEX_UPPER_CHAR[(b_ & 0xF0) >> 4]; line[i * 3 + 12] = HEX_UPPER_CHAR[b_ & 0xF]; if (b_ >= 32 && b_ < 127) { line[61 + i] = (char) b_; } else { line[61 + i] = '.'; } } } if (begin < 8 && end > 8) { line[34] = '-'; } return new String(line); } /** Dump a byte array into a {@link PrintStream} in human readable format */ public static void dump(PrintStream out, byte[] b, int off, int len) { int end = off + len; int offDiv16 = off / 16; int endDiv16 = end / 16; if (offDiv16 == endDiv16) { out.println(dumpLine(b, offDiv16, off % 16, end % 16)); } else { out.println(dumpLine(b, offDiv16, off % 16, 16)); for (int i = offDiv16 + 1; i < endDiv16; i ++) { out.println(dumpLine(b, i, 0, 16)); } if (end % 16 > 0) { out.println(dumpLine(b, endDiv16, 0, end % 16)); } } } /** Dump a byte array into a {@link PrintStream} in human readable format */ public static void dump(PrintStream out, byte[] b) { dump(out, b, 0, b.length); } /** Dump a byte array into a {@link PrintWriter} in human readable format */ public static void dump(PrintWriter out, byte[] b, int off, int len) { int end = off + len; int offDiv16 = off / 16; int endDiv16 = end / 16; if (offDiv16 == endDiv16) { out.println(dumpLine(b, offDiv16, off % 16, end % 16)); } else { out.println(dumpLine(b, offDiv16, off % 16, 16)); for (int i = offDiv16 + 1; i < endDiv16; i ++) { out.println(dumpLine(b, i, 0, 16)); } if (end % 16 > 0) { out.println(dumpLine(b, endDiv16, 0, end % 16)); } } } /** Dump a byte array into a {@link PrintWriter} in human readable format */ public static void dump(PrintWriter out, byte[] b) { dump(out, b, 0, b.length); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy