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