001/* 002 * Copyright (C) 2011 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015package com.google.common.hash; 016 017import static com.google.common.base.Preconditions.checkArgument; 018import static com.google.common.base.Preconditions.checkNotNull; 019 020import com.google.common.annotations.Beta; 021import com.google.common.base.Supplier; 022import java.security.Key; 023import java.util.ArrayList; 024import java.util.Arrays; 025import java.util.Iterator; 026import java.util.List; 027import java.util.zip.Adler32; 028import java.util.zip.CRC32; 029import java.util.zip.Checksum; 030import javax.crypto.spec.SecretKeySpec; 031import org.checkerframework.checker.nullness.compatqual.NullableDecl; 032 033/** 034 * Static methods to obtain {@link HashFunction} instances, and other static hashing-related 035 * utilities. 036 * 037 * <p>A comparison of the various hash functions can be found <a 038 * href="http://goo.gl/jS7HH">here</a>. 039 * 040 * @author Kevin Bourrillion 041 * @author Dimitris Andreou 042 * @author Kurt Alfred Kluever 043 * @since 11.0 044 */ 045@Beta 046public final class Hashing { 047 /** 048 * Returns a general-purpose, <b>temporary-use</b>, non-cryptographic hash function. The algorithm 049 * the returned function implements is unspecified and subject to change without notice. 050 * 051 * <p><b>Warning:</b> a new random seed for these functions is chosen each time the {@code 052 * Hashing} class is loaded. <b>Do not use this method</b> if hash codes may escape the current 053 * process in any way, for example being sent over RPC, or saved to disk. For a general-purpose, 054 * non-cryptographic hash function that will never change behavior, we suggest {@link 055 * #murmur3_128}. 056 * 057 * <p>Repeated calls to this method on the same loaded {@code Hashing} class, using the same value 058 * for {@code minimumBits}, will return identically-behaving {@link HashFunction} instances. 059 * 060 * @param minimumBits a positive integer (can be arbitrarily large) 061 * @return a hash function, described above, that produces hash codes of length {@code 062 * minimumBits} or greater 063 */ 064 public static HashFunction goodFastHash(int minimumBits) { 065 int bits = checkPositiveAndMakeMultipleOf32(minimumBits); 066 067 if (bits == 32) { 068 return Murmur3_32HashFunction.GOOD_FAST_HASH_32; 069 } 070 if (bits <= 128) { 071 return Murmur3_128HashFunction.GOOD_FAST_HASH_128; 072 } 073 074 // Otherwise, join together some 128-bit murmur3s 075 int hashFunctionsNeeded = (bits + 127) / 128; 076 HashFunction[] hashFunctions = new HashFunction[hashFunctionsNeeded]; 077 hashFunctions[0] = Murmur3_128HashFunction.GOOD_FAST_HASH_128; 078 int seed = GOOD_FAST_HASH_SEED; 079 for (int i = 1; i < hashFunctionsNeeded; i++) { 080 seed += 1500450271; // a prime; shouldn't matter 081 hashFunctions[i] = murmur3_128(seed); 082 } 083 return new ConcatenatedHashFunction(hashFunctions); 084 } 085 086 /** 087 * Used to randomize {@link #goodFastHash} instances, so that programs which persist anything 088 * dependent on the hash codes they produce will fail sooner. 089 */ 090 static final int GOOD_FAST_HASH_SEED = (int) System.currentTimeMillis(); 091 092 /** 093 * Returns a hash function implementing the <a 094 * href="https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp">32-bit murmur3 095 * algorithm, x86 variant</a> (little-endian variant), using the given seed value. 096 * 097 * <p>The exact C++ equivalent is the MurmurHash3_x86_32 function (Murmur3A). 098 */ 099 public static HashFunction murmur3_32(int seed) { 100 return new Murmur3_32HashFunction(seed); 101 } 102 103 /** 104 * Returns a hash function implementing the <a 105 * href="https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp">32-bit murmur3 106 * algorithm, x86 variant</a> (little-endian variant), using a seed value of zero. 107 * 108 * <p>The exact C++ equivalent is the MurmurHash3_x86_32 function (Murmur3A). 109 */ 110 public static HashFunction murmur3_32() { 111 return Murmur3_32HashFunction.MURMUR3_32; 112 } 113 114 /** 115 * Returns a hash function implementing the <a 116 * href="https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp">128-bit murmur3 117 * algorithm, x64 variant</a> (little-endian variant), using the given seed value. 118 * 119 * <p>The exact C++ equivalent is the MurmurHash3_x64_128 function (Murmur3F). 120 */ 121 public static HashFunction murmur3_128(int seed) { 122 return new Murmur3_128HashFunction(seed); 123 } 124 125 /** 126 * Returns a hash function implementing the <a 127 * href="https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp">128-bit murmur3 128 * algorithm, x64 variant</a> (little-endian variant), using a seed value of zero. 129 * 130 * <p>The exact C++ equivalent is the MurmurHash3_x64_128 function (Murmur3F). 131 */ 132 public static HashFunction murmur3_128() { 133 return Murmur3_128HashFunction.MURMUR3_128; 134 } 135 136 /** 137 * Returns a hash function implementing the <a href="https://131002.net/siphash/">64-bit 138 * SipHash-2-4 algorithm</a> using a seed value of {@code k = 00 01 02 ...}. 139 * 140 * @since 15.0 141 */ 142 public static HashFunction sipHash24() { 143 return SipHashFunction.SIP_HASH_24; 144 } 145 146 /** 147 * Returns a hash function implementing the <a href="https://131002.net/siphash/">64-bit 148 * SipHash-2-4 algorithm</a> using the given seed. 149 * 150 * @since 15.0 151 */ 152 public static HashFunction sipHash24(long k0, long k1) { 153 return new SipHashFunction(2, 4, k0, k1); 154 } 155 156 /** 157 * Returns a hash function implementing the MD5 hash algorithm (128 hash bits). 158 * 159 * @deprecated If you must interoperate with a system that requires MD5, then use this method, 160 * despite its deprecation. But if you can choose your hash function, avoid MD5, which is 161 * neither fast nor secure. As of January 2017, we suggest: 162 * <ul> 163 * <li>For security: 164 * {@link Hashing#sha256} or a higher-level API. 165 * <li>For speed: {@link Hashing#goodFastHash}, though see its docs for caveats. 166 * </ul> 167 */ 168 @Deprecated 169 public static HashFunction md5() { 170 return Md5Holder.MD5; 171 } 172 173 private static class Md5Holder { 174 static final HashFunction MD5 = new MessageDigestHashFunction("MD5", "Hashing.md5()"); 175 } 176 177 /** 178 * Returns a hash function implementing the SHA-1 algorithm (160 hash bits). 179 * 180 * @deprecated If you must interoperate with a system that requires SHA-1, then use this method, 181 * despite its deprecation. But if you can choose your hash function, avoid SHA-1, which is 182 * neither fast nor secure. As of January 2017, we suggest: 183 * <ul> 184 * <li>For security: 185 * {@link Hashing#sha256} or a higher-level API. 186 * <li>For speed: {@link Hashing#goodFastHash}, though see its docs for caveats. 187 * </ul> 188 */ 189 @Deprecated 190 public static HashFunction sha1() { 191 return Sha1Holder.SHA_1; 192 } 193 194 private static class Sha1Holder { 195 static final HashFunction SHA_1 = new MessageDigestHashFunction("SHA-1", "Hashing.sha1()"); 196 } 197 198 /** Returns a hash function implementing the SHA-256 algorithm (256 hash bits). */ 199 public static HashFunction sha256() { 200 return Sha256Holder.SHA_256; 201 } 202 203 private static class Sha256Holder { 204 static final HashFunction SHA_256 = 205 new MessageDigestHashFunction("SHA-256", "Hashing.sha256()"); 206 } 207 208 /** 209 * Returns a hash function implementing the SHA-384 algorithm (384 hash bits). 210 * 211 * @since 19.0 212 */ 213 public static HashFunction sha384() { 214 return Sha384Holder.SHA_384; 215 } 216 217 private static class Sha384Holder { 218 static final HashFunction SHA_384 = 219 new MessageDigestHashFunction("SHA-384", "Hashing.sha384()"); 220 } 221 222 /** Returns a hash function implementing the SHA-512 algorithm (512 hash bits). */ 223 public static HashFunction sha512() { 224 return Sha512Holder.SHA_512; 225 } 226 227 private static class Sha512Holder { 228 static final HashFunction SHA_512 = 229 new MessageDigestHashFunction("SHA-512", "Hashing.sha512()"); 230 } 231 232 /** 233 * Returns a hash function implementing the Message Authentication Code (MAC) algorithm, using the 234 * MD5 (128 hash bits) hash function and the given secret key. 235 * 236 * 237 * @param key the secret key 238 * @throws IllegalArgumentException if the given key is inappropriate for initializing this MAC 239 * @since 20.0 240 */ 241 public static HashFunction hmacMd5(Key key) { 242 return new MacHashFunction("HmacMD5", key, hmacToString("hmacMd5", key)); 243 } 244 245 /** 246 * Returns a hash function implementing the Message Authentication Code (MAC) algorithm, using the 247 * MD5 (128 hash bits) hash function and a {@link SecretKeySpec} created from the given byte array 248 * and the MD5 algorithm. 249 * 250 * 251 * @param key the key material of the secret key 252 * @since 20.0 253 */ 254 public static HashFunction hmacMd5(byte[] key) { 255 return hmacMd5(new SecretKeySpec(checkNotNull(key), "HmacMD5")); 256 } 257 258 /** 259 * Returns a hash function implementing the Message Authentication Code (MAC) algorithm, using the 260 * SHA-1 (160 hash bits) hash function and the given secret key. 261 * 262 * 263 * @param key the secret key 264 * @throws IllegalArgumentException if the given key is inappropriate for initializing this MAC 265 * @since 20.0 266 */ 267 public static HashFunction hmacSha1(Key key) { 268 return new MacHashFunction("HmacSHA1", key, hmacToString("hmacSha1", key)); 269 } 270 271 /** 272 * Returns a hash function implementing the Message Authentication Code (MAC) algorithm, using the 273 * SHA-1 (160 hash bits) hash function and a {@link SecretKeySpec} created from the given byte 274 * array and the SHA-1 algorithm. 275 * 276 * 277 * @param key the key material of the secret key 278 * @since 20.0 279 */ 280 public static HashFunction hmacSha1(byte[] key) { 281 return hmacSha1(new SecretKeySpec(checkNotNull(key), "HmacSHA1")); 282 } 283 284 /** 285 * Returns a hash function implementing the Message Authentication Code (MAC) algorithm, using the 286 * SHA-256 (256 hash bits) hash function and the given secret key. 287 * 288 * 289 * @param key the secret key 290 * @throws IllegalArgumentException if the given key is inappropriate for initializing this MAC 291 * @since 20.0 292 */ 293 public static HashFunction hmacSha256(Key key) { 294 return new MacHashFunction("HmacSHA256", key, hmacToString("hmacSha256", key)); 295 } 296 297 /** 298 * Returns a hash function implementing the Message Authentication Code (MAC) algorithm, using the 299 * SHA-256 (256 hash bits) hash function and a {@link SecretKeySpec} created from the given byte 300 * array and the SHA-256 algorithm. 301 * 302 * 303 * @param key the key material of the secret key 304 * @since 20.0 305 */ 306 public static HashFunction hmacSha256(byte[] key) { 307 return hmacSha256(new SecretKeySpec(checkNotNull(key), "HmacSHA256")); 308 } 309 310 /** 311 * Returns a hash function implementing the Message Authentication Code (MAC) algorithm, using the 312 * SHA-512 (512 hash bits) hash function and the given secret key. 313 * 314 * 315 * @param key the secret key 316 * @throws IllegalArgumentException if the given key is inappropriate for initializing this MAC 317 * @since 20.0 318 */ 319 public static HashFunction hmacSha512(Key key) { 320 return new MacHashFunction("HmacSHA512", key, hmacToString("hmacSha512", key)); 321 } 322 323 /** 324 * Returns a hash function implementing the Message Authentication Code (MAC) algorithm, using the 325 * SHA-512 (512 hash bits) hash function and a {@link SecretKeySpec} created from the given byte 326 * array and the SHA-512 algorithm. 327 * 328 * 329 * @param key the key material of the secret key 330 * @since 20.0 331 */ 332 public static HashFunction hmacSha512(byte[] key) { 333 return hmacSha512(new SecretKeySpec(checkNotNull(key), "HmacSHA512")); 334 } 335 336 private static String hmacToString(String methodName, Key key) { 337 return String.format( 338 "Hashing.%s(Key[algorithm=%s, format=%s])", 339 methodName, key.getAlgorithm(), key.getFormat()); 340 } 341 342 /** 343 * Returns a hash function implementing the CRC32C checksum algorithm (32 hash bits) as described 344 * by RFC 3720, Section 12.1. 345 * 346 * <p>This function is best understood as a <a 347 * href="https://en.wikipedia.org/wiki/Checksum">checksum</a> rather than a true <a 348 * href="https://en.wikipedia.org/wiki/Hash_function">hash function</a>. 349 * 350 * @since 18.0 351 */ 352 public static HashFunction crc32c() { 353 return Crc32cHashFunction.CRC_32_C; 354 } 355 356 /** 357 * Returns a hash function implementing the CRC-32 checksum algorithm (32 hash bits). 358 * 359 * <p>To get the {@code long} value equivalent to {@link Checksum#getValue()} for a {@code 360 * HashCode} produced by this function, use {@link HashCode#padToLong()}. 361 * 362 * <p>This function is best understood as a <a 363 * href="https://en.wikipedia.org/wiki/Checksum">checksum</a> rather than a true <a 364 * href="https://en.wikipedia.org/wiki/Hash_function">hash function</a>. 365 * 366 * @since 14.0 367 */ 368 public static HashFunction crc32() { 369 return ChecksumType.CRC_32.hashFunction; 370 } 371 372 /** 373 * Returns a hash function implementing the Adler-32 checksum algorithm (32 hash bits). 374 * 375 * <p>To get the {@code long} value equivalent to {@link Checksum#getValue()} for a {@code 376 * HashCode} produced by this function, use {@link HashCode#padToLong()}. 377 * 378 * <p>This function is best understood as a <a 379 * href="https://en.wikipedia.org/wiki/Checksum">checksum</a> rather than a true <a 380 * href="https://en.wikipedia.org/wiki/Hash_function">hash function</a>. 381 * 382 * @since 14.0 383 */ 384 public static HashFunction adler32() { 385 return ChecksumType.ADLER_32.hashFunction; 386 } 387 388 enum ChecksumType implements Supplier<Checksum> { 389 CRC_32("Hashing.crc32()") { 390 @Override 391 public Checksum get() { 392 return new CRC32(); 393 } 394 }, 395 ADLER_32("Hashing.adler32()") { 396 @Override 397 public Checksum get() { 398 return new Adler32(); 399 } 400 }; 401 402 public final HashFunction hashFunction; 403 404 ChecksumType(String toString) { 405 this.hashFunction = new ChecksumHashFunction(this, 32, toString); 406 } 407 } 408 409 /** 410 * Returns a hash function implementing FarmHash's Fingerprint64, an open-source algorithm. 411 * 412 * <p>This is designed for generating persistent fingerprints of strings. It isn't 413 * cryptographically secure, but it produces a high-quality hash with fewer collisions than some 414 * alternatives we've used in the past. 415 * 416 * <p>FarmHash fingerprints are encoded by {@link HashCode#asBytes} in little-endian order. This 417 * means {@link HashCode#asLong} is guaranteed to return the same value that 418 * farmhash::Fingerprint64() would for the same input (when compared using {@link 419 * com.google.common.primitives.UnsignedLongs}'s encoding of 64-bit unsigned numbers). 420 * 421 * <p>This function is best understood as a <a 422 * href="https://en.wikipedia.org/wiki/Fingerprint_(computing)">fingerprint</a> rather than a true 423 * <a href="https://en.wikipedia.org/wiki/Hash_function">hash function</a>. 424 * 425 * @since 20.0 426 */ 427 public static HashFunction farmHashFingerprint64() { 428 return FarmHashFingerprint64.FARMHASH_FINGERPRINT_64; 429 } 430 431 /** 432 * Assigns to {@code hashCode} a "bucket" in the range {@code [0, buckets)}, in a uniform manner 433 * that minimizes the need for remapping as {@code buckets} grows. That is, {@code 434 * consistentHash(h, n)} equals: 435 * 436 * <ul> 437 * <li>{@code n - 1}, with approximate probability {@code 1/n} 438 * <li>{@code consistentHash(h, n - 1)}, otherwise (probability {@code 1 - 1/n}) 439 * </ul> 440 * 441 * <p>This method is suitable for the common use case of dividing work among buckets that meet the 442 * following conditions: 443 * 444 * <ul> 445 * <li>You want to assign the same fraction of inputs to each bucket. 446 * <li>When you reduce the number of buckets, you can accept that the most recently added 447 * buckets will be removed first. More concretely, if you are dividing traffic among tasks, 448 * you can decrease the number of tasks from 15 and 10, killing off the final 5 tasks, and 449 * {@code consistentHash} will handle it. If, however, you are dividing traffic among 450 * servers {@code alpha}, {@code bravo}, and {@code charlie} and you occasionally need to 451 * take each of the servers offline, {@code consistentHash} will be a poor fit: It provides 452 * no way for you to specify which of the three buckets is disappearing. Thus, if your 453 * buckets change from {@code [alpha, bravo, charlie]} to {@code [bravo, charlie]}, it will 454 * assign all the old {@code alpha} traffic to {@code bravo} and all the old {@code bravo} 455 * traffic to {@code charlie}, rather than letting {@code bravo} keep its traffic. 456 * </ul> 457 * 458 * 459 * <p>See the <a href="http://en.wikipedia.org/wiki/Consistent_hashing">Wikipedia article on 460 * consistent hashing</a> for more information. 461 */ 462 public static int consistentHash(HashCode hashCode, int buckets) { 463 return consistentHash(hashCode.padToLong(), buckets); 464 } 465 466 /** 467 * Assigns to {@code input} a "bucket" in the range {@code [0, buckets)}, in a uniform manner that 468 * minimizes the need for remapping as {@code buckets} grows. That is, {@code consistentHash(h, 469 * n)} equals: 470 * 471 * <ul> 472 * <li>{@code n - 1}, with approximate probability {@code 1/n} 473 * <li>{@code consistentHash(h, n - 1)}, otherwise (probability {@code 1 - 1/n}) 474 * </ul> 475 * 476 * <p>This method is suitable for the common use case of dividing work among buckets that meet the 477 * following conditions: 478 * 479 * <ul> 480 * <li>You want to assign the same fraction of inputs to each bucket. 481 * <li>When you reduce the number of buckets, you can accept that the most recently added 482 * buckets will be removed first. More concretely, if you are dividing traffic among tasks, 483 * you can decrease the number of tasks from 15 and 10, killing off the final 5 tasks, and 484 * {@code consistentHash} will handle it. If, however, you are dividing traffic among 485 * servers {@code alpha}, {@code bravo}, and {@code charlie} and you occasionally need to 486 * take each of the servers offline, {@code consistentHash} will be a poor fit: It provides 487 * no way for you to specify which of the three buckets is disappearing. Thus, if your 488 * buckets change from {@code [alpha, bravo, charlie]} to {@code [bravo, charlie]}, it will 489 * assign all the old {@code alpha} traffic to {@code bravo} and all the old {@code bravo} 490 * traffic to {@code charlie}, rather than letting {@code bravo} keep its traffic. 491 * </ul> 492 * 493 * 494 * <p>See the <a href="http://en.wikipedia.org/wiki/Consistent_hashing">Wikipedia article on 495 * consistent hashing</a> for more information. 496 */ 497 public static int consistentHash(long input, int buckets) { 498 checkArgument(buckets > 0, "buckets must be positive: %s", buckets); 499 LinearCongruentialGenerator generator = new LinearCongruentialGenerator(input); 500 int candidate = 0; 501 int next; 502 503 // Jump from bucket to bucket until we go out of range 504 while (true) { 505 next = (int) ((candidate + 1) / generator.nextDouble()); 506 if (next >= 0 && next < buckets) { 507 candidate = next; 508 } else { 509 return candidate; 510 } 511 } 512 } 513 514 /** 515 * Returns a hash code, having the same bit length as each of the input hash codes, that combines 516 * the information of these hash codes in an ordered fashion. That is, whenever two equal hash 517 * codes are produced by two calls to this method, it is <i>as likely as possible</i> that each 518 * was computed from the <i>same</i> input hash codes in the <i>same</i> order. 519 * 520 * @throws IllegalArgumentException if {@code hashCodes} is empty, or the hash codes do not all 521 * have the same bit length 522 */ 523 public static HashCode combineOrdered(Iterable<HashCode> hashCodes) { 524 Iterator<HashCode> iterator = hashCodes.iterator(); 525 checkArgument(iterator.hasNext(), "Must be at least 1 hash code to combine."); 526 int bits = iterator.next().bits(); 527 byte[] resultBytes = new byte[bits / 8]; 528 for (HashCode hashCode : hashCodes) { 529 byte[] nextBytes = hashCode.asBytes(); 530 checkArgument( 531 nextBytes.length == resultBytes.length, "All hashcodes must have the same bit length."); 532 for (int i = 0; i < nextBytes.length; i++) { 533 resultBytes[i] = (byte) (resultBytes[i] * 37 ^ nextBytes[i]); 534 } 535 } 536 return HashCode.fromBytesNoCopy(resultBytes); 537 } 538 539 /** 540 * Returns a hash code, having the same bit length as each of the input hash codes, that combines 541 * the information of these hash codes in an unordered fashion. That is, whenever two equal hash 542 * codes are produced by two calls to this method, it is <i>as likely as possible</i> that each 543 * was computed from the <i>same</i> input hash codes in <i>some</i> order. 544 * 545 * @throws IllegalArgumentException if {@code hashCodes} is empty, or the hash codes do not all 546 * have the same bit length 547 */ 548 public static HashCode combineUnordered(Iterable<HashCode> hashCodes) { 549 Iterator<HashCode> iterator = hashCodes.iterator(); 550 checkArgument(iterator.hasNext(), "Must be at least 1 hash code to combine."); 551 byte[] resultBytes = new byte[iterator.next().bits() / 8]; 552 for (HashCode hashCode : hashCodes) { 553 byte[] nextBytes = hashCode.asBytes(); 554 checkArgument( 555 nextBytes.length == resultBytes.length, "All hashcodes must have the same bit length."); 556 for (int i = 0; i < nextBytes.length; i++) { 557 resultBytes[i] += nextBytes[i]; 558 } 559 } 560 return HashCode.fromBytesNoCopy(resultBytes); 561 } 562 563 /** Checks that the passed argument is positive, and ceils it to a multiple of 32. */ 564 static int checkPositiveAndMakeMultipleOf32(int bits) { 565 checkArgument(bits > 0, "Number of bits must be positive"); 566 return (bits + 31) & ~31; 567 } 568 569 /** 570 * Returns a hash function which computes its hash code by concatenating the hash codes of the 571 * underlying hash functions together. This can be useful if you need to generate hash codes of a 572 * specific length. 573 * 574 * <p>For example, if you need 1024-bit hash codes, you could join two {@link Hashing#sha512} hash 575 * functions together: {@code Hashing.concatenating(Hashing.sha512(), Hashing.sha512())}. 576 * 577 * @since 19.0 578 */ 579 public static HashFunction concatenating( 580 HashFunction first, HashFunction second, HashFunction... rest) { 581 // We can't use Lists.asList() here because there's no hash->collect dependency 582 List<HashFunction> list = new ArrayList<>(); 583 list.add(first); 584 list.add(second); 585 list.addAll(Arrays.asList(rest)); 586 return new ConcatenatedHashFunction(list.toArray(new HashFunction[0])); 587 } 588 589 /** 590 * Returns a hash function which computes its hash code by concatenating the hash codes of the 591 * underlying hash functions together. This can be useful if you need to generate hash codes of a 592 * specific length. 593 * 594 * <p>For example, if you need 1024-bit hash codes, you could join two {@link Hashing#sha512} hash 595 * functions together: {@code Hashing.concatenating(Hashing.sha512(), Hashing.sha512())}. 596 * 597 * @since 19.0 598 */ 599 public static HashFunction concatenating(Iterable<HashFunction> hashFunctions) { 600 checkNotNull(hashFunctions); 601 // We can't use Iterables.toArray() here because there's no hash->collect dependency 602 List<HashFunction> list = new ArrayList<>(); 603 for (HashFunction hashFunction : hashFunctions) { 604 list.add(hashFunction); 605 } 606 checkArgument(list.size() > 0, "number of hash functions (%s) must be > 0", list.size()); 607 return new ConcatenatedHashFunction(list.toArray(new HashFunction[0])); 608 } 609 610 private static final class ConcatenatedHashFunction extends AbstractCompositeHashFunction { 611 private final int bits; 612 613 private ConcatenatedHashFunction(HashFunction... functions) { 614 super(functions); 615 int bitSum = 0; 616 for (HashFunction function : functions) { 617 bitSum += function.bits(); 618 checkArgument( 619 function.bits() % 8 == 0, 620 "the number of bits (%s) in hashFunction (%s) must be divisible by 8", 621 function.bits(), 622 function); 623 } 624 this.bits = bitSum; 625 } 626 627 @Override 628 HashCode makeHash(Hasher[] hashers) { 629 byte[] bytes = new byte[bits / 8]; 630 int i = 0; 631 for (Hasher hasher : hashers) { 632 HashCode newHash = hasher.hash(); 633 i += newHash.writeBytesTo(bytes, i, newHash.bits() / 8); 634 } 635 return HashCode.fromBytesNoCopy(bytes); 636 } 637 638 @Override 639 public int bits() { 640 return bits; 641 } 642 643 @Override 644 public boolean equals(@NullableDecl Object object) { 645 if (object instanceof ConcatenatedHashFunction) { 646 ConcatenatedHashFunction other = (ConcatenatedHashFunction) object; 647 return Arrays.equals(functions, other.functions); 648 } 649 return false; 650 } 651 652 @Override 653 public int hashCode() { 654 return Arrays.hashCode(functions) * 31 + bits; 655 } 656 } 657 658 /** 659 * Linear CongruentialGenerator to use for consistent hashing. See 660 * http://en.wikipedia.org/wiki/Linear_congruential_generator 661 */ 662 private static final class LinearCongruentialGenerator { 663 private long state; 664 665 public LinearCongruentialGenerator(long seed) { 666 this.state = seed; 667 } 668 669 public double nextDouble() { 670 state = 2862933555777941757L * state + 1; 671 return ((double) ((int) (state >>> 33) + 1)) / (0x1.0p31); 672 } 673 } 674 675 private Hashing() {} 676}