Home | History | Annotate | Download | only in hash
      1 /*
      2  * Copyright (C) 2011 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
      5  * in compliance with the License. You may obtain a copy of the License at
      6  *
      7  * http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the License
     10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     11  * or implied. See the License for the specific language governing permissions and limitations under
     12  * the License.
     13  */
     14 
     15 package com.google.common.hash;
     16 
     17 import com.google.common.annotations.Beta;
     18 
     19 import java.nio.charset.Charset;
     20 
     21 /**
     22  * A {@link PrimitiveSink} that can compute a hash code after reading the input. Each hasher should
     23  * translate all multibyte values ({@link #putInt(int)}, {@link #putLong(long)}, etc) to bytes
     24  * in little-endian order.
     25  *
     26  * <p><b>Warning:</b> The result of calling any methods after calling {@link #hash} is undefined.
     27  *
     28  * <p><b>Warning:</b> Using a specific character encoding when hashing a {@link CharSequence} with
     29  * {@link #putString(CharSequence, Charset)} is generally only useful for cross-language
     30  * compatibility (otherwise prefer {@link #putUnencodedChars}). However, the character encodings
     31  * must be identical across languages. Also beware that {@link Charset} definitions may occasionally
     32  * change between Java releases.
     33  *
     34  * <p><b>Warning:</b> Chunks of data that are put into the {@link Hasher} are not delimited.
     35  * The resulting {@link HashCode} is dependent only on the bytes inserted, and the order in which
     36  * they were inserted, not how those bytes were chunked into discrete put() operations. For example,
     37  * the following three expressions all generate colliding hash codes: <pre>   {@code
     38  *
     39  *   newHasher().putByte(b1).putByte(b2).putByte(b3).hash()
     40  *   newHasher().putByte(b1).putBytes(new byte[] { b2, b3 }).hash()
     41  *   newHasher().putBytes(new byte[] { b1, b2, b3 }).hash()}</pre>
     42  *
     43  * <p>If you wish to avoid this, you should either prepend or append the size of each chunk. Keep in
     44  * mind that when dealing with char sequences, the encoded form of two concatenated char sequences
     45  * is not equivalent to the concatenation of their encoded form. Therefore,
     46  * {@link #putString(CharSequence, Charset)} should only be used consistently with <i>complete</i>
     47  * sequences and not broken into chunks.
     48  *
     49  * @author Kevin Bourrillion
     50  * @since 11.0
     51  */
     52 @Beta
     53 public interface Hasher extends PrimitiveSink {
     54   @Override Hasher putByte(byte b);
     55   @Override Hasher putBytes(byte[] bytes);
     56   @Override Hasher putBytes(byte[] bytes, int off, int len);
     57   @Override Hasher putShort(short s);
     58   @Override Hasher putInt(int i);
     59   @Override Hasher putLong(long l);
     60 
     61   /**
     62    * Equivalent to {@code putInt(Float.floatToRawIntBits(f))}.
     63    */
     64   @Override Hasher putFloat(float f);
     65 
     66   /**
     67    * Equivalent to {@code putLong(Double.doubleToRawLongBits(d))}.
     68    */
     69   @Override Hasher putDouble(double d);
     70 
     71   /**
     72    * Equivalent to {@code putByte(b ? (byte) 1 : (byte) 0)}.
     73    */
     74   @Override Hasher putBoolean(boolean b);
     75   @Override Hasher putChar(char c);
     76 
     77   /**
     78    * Equivalent to processing each {@code char} value in the {@code CharSequence}, in order.
     79    * The input must not be updated while this method is in progress.
     80    *
     81    * @since 15.0 (since 11.0 as putString(CharSequence)).
     82    */
     83   @Override Hasher putUnencodedChars(CharSequence charSequence);
     84 
     85   /**
     86    * Equivalent to {@code putBytes(charSequence.toString().getBytes(charset))}.
     87    */
     88   @Override Hasher putString(CharSequence charSequence, Charset charset);
     89 
     90   /**
     91    * A simple convenience for {@code funnel.funnel(object, this)}.
     92    */
     93   <T> Hasher putObject(T instance, Funnel<? super T> funnel);
     94 
     95   /**
     96    * Computes a hash code based on the data that have been provided to this hasher. The result is
     97    * unspecified if this method is called more than once on the same instance.
     98    */
     99   HashCode hash();
    100 }
    101