11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in compliance with the License. You may obtain a copy of the License at
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software distributed under the License
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * or implied. See the License for the specific language governing permissions and limitations under
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the License.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.hash;
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
170888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.Preconditions.checkArgument;
180888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull;
190888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.Preconditions.checkState;
200888a09821a98ac0680fad765217302858e70fa4Paul Duffin
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Preconditions;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.primitives.Ints;
240888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.primitives.UnsignedInts;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
260888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.io.Serializable;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.security.MessageDigest;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport javax.annotation.Nullable;
307dd252788645e940eada959bdde927426e2531c9Paul Duffin
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An immutable hash code of arbitrary bit length.
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Dimitris Andreou
350888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @author Kurt Alfred Kluever
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class HashCode {
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  HashCode() {}
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
430888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Returns the number of bits in this hash code; a positive multiple of 8.
440888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
450888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public abstract int bits();
460888a09821a98ac0680fad765217302858e70fa4Paul Duffin
470888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the first four bytes of {@linkplain #asBytes() this hashcode's bytes}, converted to
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * an {@code int} value in little-endian order.
507dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
517dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @throws IllegalStateException if {@code bits() < 32}
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public abstract int asInt();
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the first eight bytes of {@linkplain #asBytes() this hashcode's bytes}, converted to
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * a {@code long} value in little-endian order.
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IllegalStateException if {@code bits() < 64}
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public abstract long asLong();
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
647dd252788645e940eada959bdde927426e2531c9Paul Duffin   * If this hashcode has enough bits, returns {@code asLong()}, otherwise returns a {@code long}
650888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * value with {@code asBytes()} as the least-significant bytes and {@code 0x00} as the remaining
660888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * most-significant bytes.
677dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
687dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @since 14.0 (since 11.0 as {@code Hashing.padToLong(HashCode)})
697dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
707dd252788645e940eada959bdde927426e2531c9Paul Duffin  public abstract long padToLong();
717dd252788645e940eada959bdde927426e2531c9Paul Duffin
727dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the value of this hash code as a byte array. The caller may modify the byte array;
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * changes to it will <i>not</i> be reflected in this {@code HashCode} object or any other arrays
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * returned by this method.
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // TODO(user): consider ByteString here, when that is available
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public abstract byte[] asBytes();
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Copies bytes from this hash code into {@code dest}.
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param dest the byte array into which the hash code will be written
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param offset the start offset in the data
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param maxLength the maximum number of bytes to write
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return the number of bytes written to {@code dest}
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IndexOutOfBoundsException if there is not enough room in {@code dest}
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public int writeBytesTo(byte[] dest, int offset, int maxLength) {
900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    maxLength = Ints.min(maxLength, bits() / 8);
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Preconditions.checkPositionIndexes(offset, offset + maxLength, dest.length);
920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    writeBytesToImpl(dest, offset, maxLength);
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return maxLength;
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
960888a09821a98ac0680fad765217302858e70fa4Paul Duffin  abstract void writeBytesToImpl(byte[] dest, int offset, int maxLength);
970888a09821a98ac0680fad765217302858e70fa4Paul Duffin
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
990888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Returns a mutable view of the underlying bytes for the given {@code HashCode} if it is a
1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * byte-based hashcode. Otherwise it returns {@link HashCode#asBytes}. Do <i>not</i> mutate this
1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * array or else you will break the immutability contract of {@code HashCode}.
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin  byte[] getBytesInternal() {
1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return asBytes();
1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1060888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1070888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Creates a 32-bit {@code HashCode} representation of the given int value. The underlying bytes
1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * are interpreted in little endian order.
1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @since 15.0 (since 12.0 in HashCodes)
1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
1130888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static HashCode fromInt(int hash) {
1140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return new IntHashCode(hash);
1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final class IntHashCode extends HashCode implements Serializable {
1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final int hash;
1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    IntHashCode(int hash) {
1210888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.hash = hash;
1220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1230888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public int bits() {
1260888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return 32;
1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public byte[] asBytes() {
1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return new byte[] {
1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) hash,
1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 8),
1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 16),
1350888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 24)};
1360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public int asInt() {
1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return hash;
1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public long asLong() {
1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new IllegalStateException("this HashCode only has 32 bits; cannot create a long");
1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1480888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public long padToLong() {
1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return UnsignedInts.toLong(hash);
1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    void writeBytesToImpl(byte[] dest, int offset, int maxLength) {
1550888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < maxLength; i++) {
1560888a09821a98ac0680fad765217302858e70fa4Paul Duffin        dest[offset + i] = (byte) (hash >> (i * 8));
1570888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
1580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1590888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private static final long serialVersionUID = 0;
1610888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1620888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1630888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
1640888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Creates a 64-bit {@code HashCode} representation of the given long value. The underlying bytes
1650888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * are interpreted in little endian order.
1660888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @since 15.0 (since 12.0 in HashCodes)
1680888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
1690888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static HashCode fromLong(long hash) {
1700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return new LongHashCode(hash);
1710888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final class LongHashCode extends HashCode implements Serializable {
1740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final long hash;
1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    LongHashCode(long hash) {
1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.hash = hash;
1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public int bits() {
1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return 64;
1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public byte[] asBytes() {
1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return new byte[] {
1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) hash,
1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 8),
1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 16),
1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 24),
1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 32),
1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 40),
1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 48),
1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin          (byte) (hash >> 56)};
1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public int asInt() {
2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return (int) hash;
2010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public long asLong() {
2050888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return hash;
2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2070888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public long padToLong() {
2100888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return hash;
2110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2120888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    void writeBytesToImpl(byte[] dest, int offset, int maxLength) {
2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < maxLength; i++) {
2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin        dest[offset + i] = (byte) (hash >> (i * 8));
2170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
2180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2190888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private static final long serialVersionUID = 0;
2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2230888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Creates a {@code HashCode} from a byte array. The array is defensively copied to preserve
2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * the immutability contract of {@code HashCode}. The array cannot be empty.
2260888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
2270888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @since 15.0 (since 12.0 in HashCodes)
2280888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
2290888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static HashCode fromBytes(byte[] bytes) {
2300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkArgument(bytes.length >= 1, "A HashCode must contain at least 1 byte.");
2310888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return fromBytesNoCopy(bytes.clone());
2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2340888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
2350888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Creates a {@code HashCode} from a byte array. The array is <i>not</i> copied defensively,
2360888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * so it must be handed-off so as to preserve the immutability contract of {@code HashCode}.
2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin  static HashCode fromBytesNoCopy(byte[] bytes) {
2390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return new BytesHashCode(bytes);
2400888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2410888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2420888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final class BytesHashCode extends HashCode implements Serializable {
2430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final byte[] bytes;
2440888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    BytesHashCode(byte[] bytes) {
2460888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.bytes = checkNotNull(bytes);
2470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2480888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public int bits() {
2510888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return bytes.length * 8;
2520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2530888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public byte[] asBytes() {
2560888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return bytes.clone();
2570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2580888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public int asInt() {
2610888a09821a98ac0680fad765217302858e70fa4Paul Duffin      checkState(bytes.length >= 4,
2620888a09821a98ac0680fad765217302858e70fa4Paul Duffin          "HashCode#asInt() requires >= 4 bytes (it only has %s bytes).", bytes.length);
2630888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return (bytes[0] & 0xFF)
2640888a09821a98ac0680fad765217302858e70fa4Paul Duffin          | ((bytes[1] & 0xFF) << 8)
2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin          | ((bytes[2] & 0xFF) << 16)
2660888a09821a98ac0680fad765217302858e70fa4Paul Duffin          | ((bytes[3] & 0xFF) << 24);
2670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2680888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public long asLong() {
2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin      checkState(bytes.length >= 8,
2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin          "HashCode#asLong() requires >= 8 bytes (it only has %s bytes).", bytes.length);
2730888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return padToLong();
2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2750888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public long padToLong() {
2780888a09821a98ac0680fad765217302858e70fa4Paul Duffin      long retVal = (bytes[0] & 0xFF);
2790888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 1; i < Math.min(bytes.length, 8); i++) {
2800888a09821a98ac0680fad765217302858e70fa4Paul Duffin        retVal |= (bytes[i] & 0xFFL) << (i * 8);
2810888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
2820888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return retVal;
2830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2840888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    void writeBytesToImpl(byte[] dest, int offset, int maxLength) {
2870888a09821a98ac0680fad765217302858e70fa4Paul Duffin      System.arraycopy(bytes, 0, dest, offset, maxLength);
2880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2890888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    byte[] getBytesInternal() {
2920888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return bytes;
2930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2940888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private static final long serialVersionUID = 0;
2960888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2970888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2980888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Creates a {@code HashCode} from a hexadecimal ({@code base 16}) encoded string. The string must
3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * be at least 2 characters long, and contain only valid, lower-cased hexadecimal characters.
3010888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
3020888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * <p>This method accepts the exact format generated by {@link #toString}. If you require more
3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * lenient {@code base 16} decoding, please use
3040888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * {@link com.google.common.io.BaseEncoding#decode} (and pass the result to {@link #fromBytes}).
3050888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
3060888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @since 15.0
3070888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
3080888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static HashCode fromString(String string) {
3090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkArgument(string.length() >= 2,
3100888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "input string (%s) must have at least 2 characters", string);
3110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkArgument(string.length() % 2 == 0,
3120888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "input string (%s) must have an even number of characters", string);
3130888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    byte[] bytes = new byte[string.length() / 2];
3150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (int i = 0; i < string.length(); i += 2) {
3160888a09821a98ac0680fad765217302858e70fa4Paul Duffin      int ch1 = decode(string.charAt(i)) << 4;
3170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      int ch2 = decode(string.charAt(i + 1));
3180888a09821a98ac0680fad765217302858e70fa4Paul Duffin      bytes[i / 2] = (byte) (ch1 + ch2);
3190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return fromBytesNoCopy(bytes);
3210888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3220888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3230888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static int decode(char ch) {
3240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (ch >= '0' && ch <= '9') {
3250888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return ch - '0';
3260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (ch >= 'a' && ch <= 'f') {
3280888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return ch - 'a' + 10;
3290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    throw new IllegalArgumentException("Illegal hexadecimal character: " + ch);
3310888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3337dd252788645e940eada959bdde927426e2531c9Paul Duffin  @Override
3340888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public final boolean equals(@Nullable Object object) {
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (object instanceof HashCode) {
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      HashCode that = (HashCode) object;
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Undocumented: this is a non-short-circuiting equals(), in case this is a cryptographic
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // hash code, in which case we don't want to leak timing information
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return MessageDigest.isEqual(this.asBytes(), that.asBytes());
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return false;
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a "Java hash code" for this {@code HashCode} instance; this is well-defined
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * (so, for example, you can safely put {@code HashCode} instances into a {@code
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * HashSet}) but is otherwise probably not what you want to use.
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3497dd252788645e940eada959bdde927426e2531c9Paul Duffin  @Override
3500888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public final int hashCode() {
3510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // If we have at least 4 bytes (32 bits), just take the first 4 bytes. Since this is
3520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // already a (presumably) high-quality hash code, any four bytes of it will do.
3530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (bits() >= 32) {
3540888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return asInt();
3550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3560888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // If we have less than 4 bytes, use them all.
3570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    byte[] bytes = asBytes();
3580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int val = (bytes[0] & 0xFF);
3590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (int i = 1; i < bytes.length; i++) {
3600888a09821a98ac0680fad765217302858e70fa4Paul Duffin      val |= ((bytes[i] & 0xFF) << (i * 8));
3610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return val;
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a string containing each byte of {@link #asBytes}, in order, as a two-digit unsigned
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * hexadecimal number in lower case.
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note that if the output is considered to be a single hexadecimal number, this hash code's
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * bytes are the <i>big-endian</i> representation of that number. This may be surprising since
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * everything else in the hashing API uniformly treats multibyte values as little-endian. But
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * this format conveniently matches that of utilities such as the UNIX {@code md5sum} command.
3730888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
3740888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * <p>To create a {@code HashCode} from its string representation, see {@link #fromString}.
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3767dd252788645e940eada959bdde927426e2531c9Paul Duffin  @Override
3770888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public final String toString() {
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    byte[] bytes = asBytes();
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    StringBuilder sb = new StringBuilder(2 * bytes.length);
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (byte b : bytes) {
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      sb.append(hexDigits[(b >> 4) & 0xf]).append(hexDigits[b & 0xf]);
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return sb.toString();
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final char[] hexDigits = "0123456789abcdef".toCharArray();
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
388