Class ByteUtils

java.lang.Object
org.bitcoinj.base.internal.ByteUtils

public class ByteUtils extends Object
Utility methods for bit, byte, and integer manipulation and conversion. Most of these were moved here from org.bitcoinj.core.Utils.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final com.google.common.io.BaseEncoding
    Deprecated.
    Use hexFormat or parseHex(String) or other available options.
    static final long
    Maximum unsigned value that can be expressed by 32 bits.
    static final int
    Maximum unsigned value that can be expressed by 16 bits.
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    static Comparator<byte[]>
    Provides a byte array comparator.
    static byte[]
    bigIntegerToBytes(BigInteger b, int numBytes)
    The built-in BigInteger.toByteArray() includes the sign bit of the number and may result in an extra byte in cases of unsigned data.
    static BigInteger
    bytesToBigInteger(byte[] bytes)
    Converts an array of bytes into a positive BigInteger.
    static boolean
    checkBitLE(byte[] data, int index)
    Checks if the given bit is set in data, using little endian (not the same as Java native big endian)
    static byte[]
    concat(byte[] b1, byte[] b2)
    Concatenate two byte arrays
    static BigInteger
    decodeCompactBits(long compact)
    The "compact" format is a representation of a whole number N using an unsigned 32 bit number similar to a floating point format.
    static BigInteger
    decodeMPI(byte[] mpi, boolean hasLength)
    MPI encoded numbers are produced by the OpenSSL BN_bn2mpi function.
    static long
     
    static byte[]
    encodeMPI(BigInteger value, boolean includeLength)
    MPI encoded numbers are produced by the OpenSSL BN_bn2mpi function.
    static String
    formatHex(byte[] bytes)
     
    static byte[]
    parseHex(String string)
     
    static int
    Read 4 bytes from the byte array (starting at the offset) as signed 32-bit integer in little endian format.
    static long
    readInt64(byte[] bytes, int offset)
    Read 8 bytes from the byte array (starting at the offset) as signed 64-bit integer in little endian format.
    static long
    Read 8 bytes from the buffer as signed 64-bit integer in little endian format.
    static int
    readUint16(byte[] bytes, int offset)
    Read 2 bytes from the byte array (starting at the offset) as unsigned 16-bit integer in little endian format.
    static int
    Read 2 bytes from the stream as unsigned 16-bit integer in little endian format.
    static int
    Read 2 bytes from the buffer as unsigned 16-bit integer in little endian format.
    static int
    readUint16BE(byte[] bytes, int offset)
    Read 2 bytes from the byte array (starting at the offset) as unsigned 16-bit integer in big endian format.
    static int
    Read 2 bytes from the buffer as unsigned 16-bit integer in big endian format.
    static long
    readUint32(byte[] bytes, int offset)
    Read 4 bytes from the byte array (starting at the offset) as unsigned 32-bit integer in little endian format.
    static long
    Read 4 bytes from the stream as unsigned 32-bit integer in little endian format.
    static long
    Read 4 bytes from the buffer as unsigned 32-bit integer in little endian format.
    static long
    readUint32BE(byte[] bytes, int offset)
    Read 4 bytes from the byte array (starting at the offset) as unsigned 32-bit integer in big endian format.
    static long
    Read 4 bytes from the buffer as unsigned 32-bit integer in big endian format.
    static byte[]
    reverseBytes(byte[] bytes)
    Returns a copy of the given byte array in reverse order.
    static void
    setBitLE(byte[] data, int index)
    Sets the given bit in data to one, using little endian (not the same as Java native big endian)
    static void
    writeInt16BE(int val, OutputStream stream)
    Write a 16-bit integer to a given output stream in big-endian format.
    static ByteBuffer
    writeInt16BE(int val, ByteBuffer buf)
    Write a 16-bit integer to a given buffer in big-endian format.
    static void
    writeInt16LE(int val, OutputStream stream)
    Write a 16-bit integer to a given output stream in little-endian format.
    static ByteBuffer
    writeInt16LE(int val, ByteBuffer buf)
    Write a 16-bit integer to a given buffer in little-endian format.
    static void
    writeInt32BE(int val, byte[] out, int offset)
    Write a 32-bit integer to a given byte array in big-endian format, starting at a given offset.
    static void
    writeInt32BE(int val, OutputStream stream)
    Write a 32-bit integer to a given output stream in big-endian format.
    static ByteBuffer
    writeInt32BE(int val, ByteBuffer buf)
    Write a 32-bit integer to a given buffer in big-endian format.
    static void
    writeInt32LE(int val, OutputStream stream)
    Write a 32-bit integer to a given output stream in little-endian format.
    static ByteBuffer
    writeInt32LE(int val, ByteBuffer buf)
    Write a 32-bit integer to a given buffer in little-endian format.
    static void
    writeInt32LE(long val, byte[] out, int offset)
    Write a 32-bit integer to a given byte array in little-endian format, starting at a given offset.
    static void
    writeInt32LE(long val, OutputStream stream)
    Write a 32-bit integer to a given output stream in little-endian format.
    static ByteBuffer
    writeInt32LE(long val, ByteBuffer buf)
    Write a 32-bit integer to a given buffer in little-endian format.
    static void
    writeInt64LE(long val, byte[] out, int offset)
    Write a 64-bit integer to a given byte array in little-endian format, starting at a given offset.
    static void
    writeInt64LE(long val, OutputStream stream)
    Write a 64-bit integer to a given output stream in little-endian format.
    static ByteBuffer
    writeInt64LE(long val, ByteBuffer buf)
    Write a 64-bit integer to a given buffer in little-endian format.
    static void
    Write a 64-bit integer to a given output stream in little-endian format.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • MAX_UNSIGNED_SHORT

      public static final int MAX_UNSIGNED_SHORT
      Maximum unsigned value that can be expressed by 16 bits.
    • MAX_UNSIGNED_INTEGER

      public static final long MAX_UNSIGNED_INTEGER
      Maximum unsigned value that can be expressed by 32 bits.
    • HEX

      @Deprecated public static final com.google.common.io.BaseEncoding HEX
      Deprecated.
      Use hexFormat or parseHex(String) or other available options.
      Hex encoding used throughout the framework. Use with ByteUtils.formatHex(byte[]) or ByteUtils.parseHex(CharSequence).
  • Constructor Details

    • ByteUtils

      public ByteUtils()
  • Method Details

    • formatHex

      public static String formatHex(byte[] bytes)
    • parseHex

      public static byte[] parseHex(String string)
    • bigIntegerToBytes

      public static byte[] bigIntegerToBytes(BigInteger b, int numBytes)

      The built-in BigInteger.toByteArray() includes the sign bit of the number and may result in an extra byte in cases of unsigned data. This method removes this extra byte.

      Assuming only positive numbers, it's possible to tell if an extra byte was added by checking if the first element of the array is 0 (0000_0000). Due to the guarantee of a minimal representation provided by BigInteger, we know that the sign bit will be the least significant bit 0000_0000 of a zero-value first byte. Otherwise the representation would not be minimal.

      This is the inverse of bytesToBigInteger(byte[]).
      Parameters:
      b - the non-negative integer to format into a byte array
      numBytes - the maximum allowed size of the resulting byte array
      Returns:
      byte array of max length numBytes
    • bytesToBigInteger

      public static BigInteger bytesToBigInteger(byte[] bytes)
      Converts an array of bytes into a positive BigInteger. This is the inverse of bigIntegerToBytes(BigInteger, int).
      Parameters:
      bytes - to convert into a BigInteger
      Returns:
      the converted BigInteger
    • writeInt16LE

      public static ByteBuffer writeInt16LE(int val, ByteBuffer buf) throws BufferOverflowException
      Write a 16-bit integer to a given buffer in little-endian format.

      The value is expected as an unsigned int as per the Java Unsigned Integer API.

      Parameters:
      val - value to be written
      buf - buffer to be written into
      Returns:
      the buffer
      Throws:
      BufferOverflowException - if the value doesn't fit the remaining buffer
    • writeInt16BE

      public static ByteBuffer writeInt16BE(int val, ByteBuffer buf) throws BufferOverflowException
      Write a 16-bit integer to a given buffer in big-endian format.

      The value is expected as an unsigned int as per the Java Unsigned Integer API.

      Parameters:
      val - value to be written
      buf - buffer to be written into
      Returns:
      the buffer
      Throws:
      BufferOverflowException - if the value doesn't fit the remaining buffer
    • writeInt32LE

      public static ByteBuffer writeInt32LE(int val, ByteBuffer buf) throws BufferOverflowException
      Write a 32-bit integer to a given buffer in little-endian format.

      The value is expected as a signed or unsigned int. If you've got an unsigned long as per the Java Unsigned Integer API, use writeInt32LE(long, ByteBuffer).

      Parameters:
      val - value to be written
      buf - buffer to be written into
      Returns:
      the buffer
      Throws:
      BufferOverflowException - if the value doesn't fit the remaining buffer
    • writeInt32LE

      public static ByteBuffer writeInt32LE(long val, ByteBuffer buf) throws BufferOverflowException
      Write a 32-bit integer to a given buffer in little-endian format.

      The value is expected as an unsigned long as per the Java Unsigned Integer API.

      Parameters:
      val - value to be written
      buf - buffer to be written into
      Returns:
      the buffer
      Throws:
      BufferOverflowException - if the value doesn't fit the remaining buffer
    • writeInt32LE

      public static void writeInt32LE(long val, byte[] out, int offset) throws ArrayIndexOutOfBoundsException
      Write a 32-bit integer to a given byte array in little-endian format, starting at a given offset.

      The value is expected as an unsigned long as per the Java Unsigned Integer API.

      Parameters:
      val - value to be written
      out - buffer to be written into
      offset - offset into the buffer
      Throws:
      ArrayIndexOutOfBoundsException - if offset points outside of the buffer, or if the value doesn't fit the remaining buffer
    • writeInt32BE

      public static ByteBuffer writeInt32BE(int val, ByteBuffer buf) throws BufferOverflowException
      Write a 32-bit integer to a given buffer in big-endian format.

      The value is expected as a signed or unsigned int.

      Parameters:
      val - value to be written
      buf - buffer to be written into
      Returns:
      the buffer
      Throws:
      BufferOverflowException - if the value doesn't fit the remaining buffer
    • writeInt32BE

      public static void writeInt32BE(int val, byte[] out, int offset) throws ArrayIndexOutOfBoundsException
      Write a 32-bit integer to a given byte array in big-endian format, starting at a given offset.

      The value is expected as a signed or unsigned int.

      Parameters:
      val - value to be written
      out - buffer to be written into
      offset - offset into the buffer
      Throws:
      ArrayIndexOutOfBoundsException - if offset points outside of the buffer, or if the value doesn't fit the remaining buffer
    • writeInt64LE

      public static ByteBuffer writeInt64LE(long val, ByteBuffer buf) throws BufferOverflowException
      Write a 64-bit integer to a given buffer in little-endian format.

      The value is expected as a signed or unsigned long.

      Parameters:
      val - value to be written
      buf - buffer to be written into
      Returns:
      the buffer
      Throws:
      BufferOverflowException - if the value doesn't fit the remaining buffer
    • writeInt64LE

      public static void writeInt64LE(long val, byte[] out, int offset) throws ArrayIndexOutOfBoundsException
      Write a 64-bit integer to a given byte array in little-endian format, starting at a given offset.

      The value is expected as a signed or unsigned long.

      Parameters:
      val - value to be written
      out - buffer to be written into
      offset - offset into the buffer
      Throws:
      ArrayIndexOutOfBoundsException - if offset points outside of the buffer, or if the value doesn't fit the remaining buffer
    • writeInt16LE

      public static void writeInt16LE(int val, OutputStream stream) throws IOException
      Write a 16-bit integer to a given output stream in little-endian format.

      The value is expected as an unsigned int as per the Java Unsigned Integer API.

      Parameters:
      val - value to be written
      stream - stream to be written into
      Throws:
      IOException - if an I/O error occurs
    • writeInt16BE

      public static void writeInt16BE(int val, OutputStream stream) throws IOException
      Write a 16-bit integer to a given output stream in big-endian format.

      The value is expected as an unsigned int as per the Java Unsigned Integer API.

      Parameters:
      val - value to be written
      stream - stream to be written into
      Throws:
      IOException - if an I/O error occurs
    • writeInt32LE

      public static void writeInt32LE(int val, OutputStream stream) throws IOException
      Write a 32-bit integer to a given output stream in little-endian format.

      The value is expected as a signed or unsigned int. If you've got an unsigned long as per the Java Unsigned Integer API, use writeInt32LE(long, OutputStream).

      Parameters:
      val - value to be written
      stream - stream to be written into
      Throws:
      IOException - if an I/O error occurs
    • writeInt32LE

      public static void writeInt32LE(long val, OutputStream stream) throws IOException
      Write a 32-bit integer to a given output stream in little-endian format.

      The value is expected as an unsigned long as per the Java Unsigned Integer API.

      Parameters:
      val - value to be written
      stream - stream to be written into
      Throws:
      IOException - if an I/O error occurs
    • writeInt32BE

      public static void writeInt32BE(int val, OutputStream stream) throws IOException
      Write a 32-bit integer to a given output stream in big-endian format.

      The value is expected as a signed or unsigned int.

      Parameters:
      val - value to be written
      stream - stream to be written into
      Throws:
      IOException - if an I/O error occurs
    • writeInt64LE

      public static void writeInt64LE(long val, OutputStream stream) throws IOException
      Write a 64-bit integer to a given output stream in little-endian format.

      The value is expected as a signed or unsigned long.

      Parameters:
      val - value to be written
      stream - stream to be written into
      Throws:
      IOException - if an I/O error occurs
    • writeInt64LE

      public static void writeInt64LE(BigInteger val, OutputStream stream) throws IOException
      Write a 64-bit integer to a given output stream in little-endian format.

      The value is expected as an unsigned BigInteger.

      Parameters:
      val - value to be written
      stream - stream to be written into
      Throws:
      IOException - if an I/O error occurs
    • readUint16

      public static int readUint16(ByteBuffer buf) throws BufferUnderflowException
      Read 2 bytes from the buffer as unsigned 16-bit integer in little endian format.
      Parameters:
      buf - buffer to be read from
      Throws:
      BufferUnderflowException - if the read value extends beyond the remaining bytes of the buffer
    • readUint16

      public static int readUint16(byte[] bytes, int offset) throws ArrayIndexOutOfBoundsException
      Read 2 bytes from the byte array (starting at the offset) as unsigned 16-bit integer in little endian format.
      Parameters:
      bytes - buffer to be read from
      offset - offset into the buffer
      Throws:
      ArrayIndexOutOfBoundsException - if offset points outside of the buffer, or if the read value extends beyond the remaining bytes of the buffer
    • readUint16BE

      public static int readUint16BE(ByteBuffer buf) throws BufferUnderflowException
      Read 2 bytes from the buffer as unsigned 16-bit integer in big endian format.
      Parameters:
      buf - buffer to be read from
      Throws:
      BufferUnderflowException - if the read value extends beyond the remaining bytes of the buffer
    • readUint16BE

      public static int readUint16BE(byte[] bytes, int offset) throws ArrayIndexOutOfBoundsException
      Read 2 bytes from the byte array (starting at the offset) as unsigned 16-bit integer in big endian format.
      Parameters:
      bytes - buffer to be read from
      offset - offset into the buffer
      Throws:
      ArrayIndexOutOfBoundsException - if offset points outside of the buffer, or if the read value extends beyond the remaining bytes of the buffer
    • readUint32

      public static long readUint32(ByteBuffer buf) throws BufferUnderflowException
      Read 4 bytes from the buffer as unsigned 32-bit integer in little endian format.
      Parameters:
      buf - buffer to be read from
      Throws:
      BufferUnderflowException - if the read value extends beyond the remaining bytes of the buffer
    • readInt32

      public static int readInt32(ByteBuffer buf) throws BufferUnderflowException
      Read 4 bytes from the byte array (starting at the offset) as signed 32-bit integer in little endian format.
      Parameters:
      buf - buffer to be read from
      Returns:
      read integer
      Throws:
      BufferUnderflowException - if the read value extends beyond the remaining bytes of the buffer
    • readUint32

      public static long readUint32(byte[] bytes, int offset) throws ArrayIndexOutOfBoundsException
      Read 4 bytes from the byte array (starting at the offset) as unsigned 32-bit integer in little endian format.
      Parameters:
      bytes - buffer to be read from
      offset - offset into the buffer
      Throws:
      ArrayIndexOutOfBoundsException - if offset points outside of the buffer, or if the read value extends beyond the remaining bytes of the buffer
    • readUint32BE

      public static long readUint32BE(ByteBuffer buf) throws BufferUnderflowException
      Read 4 bytes from the buffer as unsigned 32-bit integer in big endian format.
      Parameters:
      buf - buffer to be read from
      Throws:
      BufferUnderflowException - if the read value extends beyond the remaining bytes of the buffer
    • readUint32BE

      public static long readUint32BE(byte[] bytes, int offset) throws ArrayIndexOutOfBoundsException
      Read 4 bytes from the byte array (starting at the offset) as unsigned 32-bit integer in big endian format.
      Parameters:
      bytes - buffer to be read from
      offset - offset into the buffer
      Throws:
      ArrayIndexOutOfBoundsException - if offset points outside of the buffer, or if the read value extends beyond the remaining bytes of the buffer
    • readInt64

      public static long readInt64(ByteBuffer buf) throws BufferUnderflowException
      Read 8 bytes from the buffer as signed 64-bit integer in little endian format.
      Parameters:
      buf - buffer to be read from
      Throws:
      BufferUnderflowException - if the read value extends beyond the remaining bytes of the buffer
    • readInt64

      public static long readInt64(byte[] bytes, int offset) throws ArrayIndexOutOfBoundsException
      Read 8 bytes from the byte array (starting at the offset) as signed 64-bit integer in little endian format.
      Parameters:
      bytes - buffer to be read from
      offset - offset into the buffer
      Throws:
      ArrayIndexOutOfBoundsException - if offset points outside of the buffer, or if the read value extends beyond the remaining bytes of the buffer
    • readUint16

      public static int readUint16(InputStream is)
      Read 2 bytes from the stream as unsigned 16-bit integer in little endian format.
      Parameters:
      is - stream to be read from
    • readUint32

      public static long readUint32(InputStream is)
      Read 4 bytes from the stream as unsigned 32-bit integer in little endian format.
      Parameters:
      is - stream to be read from
    • reverseBytes

      public static byte[] reverseBytes(byte[] bytes)
      Returns a copy of the given byte array in reverse order.
    • decodeMPI

      public static BigInteger decodeMPI(byte[] mpi, boolean hasLength)
      MPI encoded numbers are produced by the OpenSSL BN_bn2mpi function. They consist of a 4 byte big endian length field, followed by the stated number of bytes representing the number in big endian format (with a sign bit).
      Parameters:
      hasLength - can be set to false if the given array is missing the 4 byte length field
    • encodeMPI

      public static byte[] encodeMPI(BigInteger value, boolean includeLength)
      MPI encoded numbers are produced by the OpenSSL BN_bn2mpi function. They consist of a 4 byte big endian length field, followed by the stated number of bytes representing the number in big endian format (with a sign bit).
      Parameters:
      includeLength - indicates whether the 4 byte length field should be included
    • decodeCompactBits

      public static BigInteger decodeCompactBits(long compact)

      The "compact" format is a representation of a whole number N using an unsigned 32 bit number similar to a floating point format. The most significant 8 bits are the unsigned exponent of base 256. This exponent can be thought of as "number of bytes of N". The lower 23 bits are the mantissa. Bit number 24 (0x800000) represents the sign of N. Therefore, N = (-1^sign) * mantissa * 256^(exponent-3).

      Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). MPI uses the most significant bit of the first byte as sign. Thus 0x1234560000 is compact 0x05123456 and 0xc0de000000 is compact 0x0600c0de. Compact 0x05c0de00 would be -0x40de000000.

      Bitcoin only uses this "compact" format for encoding difficulty targets, which are unsigned 256bit quantities. Thus, all the complexities of the sign bit and using base 256 are probably an implementation accident.

    • encodeCompactBits

      public static long encodeCompactBits(BigInteger value)
      See Also:
    • checkBitLE

      public static boolean checkBitLE(byte[] data, int index)
      Checks if the given bit is set in data, using little endian (not the same as Java native big endian)
    • setBitLE

      public static void setBitLE(byte[] data, int index)
      Sets the given bit in data to one, using little endian (not the same as Java native big endian)
    • arrayUnsignedComparator

      public static Comparator<byte[]> arrayUnsignedComparator()
      Provides a byte array comparator.
      Returns:
      A comparator for byte[]
    • concat

      public static byte[] concat(byte[] b1, byte[] b2)
      Concatenate two byte arrays
      Parameters:
      b1 - first byte array
      b2 - second byte array
      Returns:
      new concatenated byte array