All Implemented Interfaces:
DataStructure
Direct Known Subclasses:
LocalHash, Peer

public class Hashextends SimpleDataStructure
A 32-byte SHA-256 hash, used throughout I2P as a destination, router, or tunnel identifier and as an integrity value for hashed data.

Creating a Hash:

  • create(byte[]) and its siblings go through a static SDSCache and are the preferred way to obtain one. The cache is keyed on the first 4 bytes of the data and holds weak references, so entries disappear under memory pressure; its maximum size is scaled by the JVM's available memory. On a cache hit the byte array passed in is handed back to SimpleByteCache for reuse and must not be touched afterwards.
  • new Hash(byte[]) bypasses the cache entirely. Use create() when the same hash may be built repeatedly.
  • create(InputStream) reads exactly 32 bytes from the stream and wraps them; it does not hash the stream. To hash arbitrary data, use SimpleDataStructure.calculateHash() or a SHA256Generator.

Rendering:

Comparison:

  • hashCode() is the precomputed value of the first 4 bytes, held in a volatile field. It is not constant-time.
  • equals() is inherited from SimpleDataStructure and is Arrays.equals(byte[], byte[]) - not constant-time, and not class-specific, so another 32-byte SimpleDataStructure such as a SessionKey holding the same bytes compares equal to a Hash.

Thread safety:

  • The data cannot be reassigned once set, so a Hash that is safely published (constructed and then handed to other threads) can be shared freely; the derived _base64ed, _base32ed and _cachedHashCode fields are volatile. SimpleDataStructure._data itself is neither final nor volatile, so a Hash built by a constructor and published through an unsynchronized data structure may expose stale data.
  • SimpleDataStructure.getData() hands out the backing array, so a caller that mutates it corrupts the cached hash code and the cached Base64 and Base32 strings, as well as any byte cache that shares the array.
  • Field Details

    • _base64ed

      private volatile String _base64ed
      Cache of the Base64 form.
    • _base32ed

      private volatile String _base32ed
      Cache of the Base32 form.
    • _cachedHashCode

      private volatile int _cachedHashCode
      Cache of the computed hash code.
    • HASH_LENGTH

      public static final int HASH_LENGTH
      Length of SHA-256 hash in bytes.
      See Also:
    • FAKE_HASH

      public static final Hash FAKE_HASH
      Placeholder all-zero hash, used as a stand-in when no real router hash is known.
    • CACHE_SIZE

      private static final int CACHE_SIZE
      Initial cache capacity, scaled by available memory by SDSCache.
      See Also:
    • _cache

      private static final SDSCache<Hash> _cache
      Shared cache of parsed hashes.
  • Constructor Details

    • Hash

      public Hash()
      Create an empty hash (data is null).
    • Hash

      public Hash(byte[] data)
      IllegalArgumentException if data is not 32 bytes (null is ok).
      Parameters:
      data - the 32 bytes to copy into the hash, with null leaving the data unset
      Throws:
      IllegalArgumentException - if data is not 32 bytes (null is ok)
  • Method Details

    • create

      public static Hash create(byte[] data)
      Pull from cache or return new

      WARNING - If the SDS is found in the cache, the passed-in byte array will be returned to the SimpleByteCache for reuse. Do NOT save a reference to the passed-in data, or use or modify it, after this call.

      Ignore this warning and you WILL corrupt the cache or other data structures.

      Parameters:
      data - the 32 bytes to wrap
      Returns:
      the cached or new hash
      Throws:
      NullPointerException - if data is null
      RuntimeException - if data is not the correct number of bytes (SDSCache wraps the constructor's IllegalArgumentException)
    • create

      public static Hash create(byte[] data, int off)
      Pull from cache or return new.
      Parameters:
      data - the buffer holding the 32 bytes to wrap
      off - the index within that buffer of the first of the 32 bytes
      Returns:
      the cached or new hash
      Throws:
      ArrayIndexOutOfBoundsException - if not enough bytes
    • create

      public static Hash create(InputStream in) throws IOException
      Pull from cache or return new.
      Parameters:
      in - the stream read for exactly the 32 bytes of the hash
      Returns:
      the cached or new hash
      Throws:
      IOException - if the stream cannot be read or holds fewer than 32 bytes
    • length

      public int length()
      Hash length in bytes.
      Specified by:
      length in class SimpleDataStructure
      Returns:
      the legal length of the byte array
    • setData

      public void setData(byte[] data)
      IllegalArgumentException if data is not 32 bytes (null is ok).
      Overrides:
      setData in class SimpleDataStructure
      Parameters:
      data - of correct length, or null
      Throws:
      IllegalArgumentException - if data is not 32 bytes (null is ok)
    • readBytes

      public void readBytes(InputStream in) throws DataFormatException, IOException
      Reads the hash from an input stream.
      Specified by:
      readBytes in interface DataStructure
      Overrides:
      readBytes in class SimpleDataStructure
      Parameters:
      in - the stream to read
      Throws:
      DataFormatException - if the data is improperly formatted
      IOException - if there was a problem reading the stream
    • hashCode

      public int hashCode()
      A Hash is a hash, so just use the first 4 bytes for speed. Precomputed at data-assignment time, so this does not read the data.
      Overrides:
      hashCode in class SimpleDataStructure
      Returns:
      the hash code
    • toBase64

      public String toBase64()
      Returns the hash as a Base64 string. Cached after the first call.
      Specified by:
      toBase64 in interface DataStructure
      Overrides:
      toBase64 in class SimpleDataStructure
      Returns:
      null on error
    • toBase32

      public String toBase32()
      The .b32.i2p form of the hash. Cached after the first call, like toBase64(), and dropped by setData() and readBytes().
      Returns:
      "{52 chars}.b32.i2p" or null if data not set.
    • clearCache

      public static void clearCache()
      Drop the shared cache of Hash instances, so cached instances become eligible for collection. Hashes already handed to callers are unaffected, and the byte arrays the cached instances held are not returned to the byte cache.