1 /* 2 * Copyright (C) 2011 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.hash; 18 19 import static com.google.common.hash.Hashing.murmur3_32; 20 21 import com.google.common.base.Charsets; 22 import com.google.common.hash.HashTestUtils.HashFn; 23 import java.util.Random; 24 import junit.framework.TestCase; 25 26 /** Tests for {@link Murmur3_32HashFunction}. */ 27 public class Murmur3Hash32Test extends TestCase { testKnownIntegerInputs()28 public void testKnownIntegerInputs() { 29 assertHash(593689054, murmur3_32().hashInt(0)); 30 assertHash(-189366624, murmur3_32().hashInt(-42)); 31 assertHash(-1134849565, murmur3_32().hashInt(42)); 32 assertHash(-1718298732, murmur3_32().hashInt(Integer.MIN_VALUE)); 33 assertHash(-1653689534, murmur3_32().hashInt(Integer.MAX_VALUE)); 34 } 35 testKnownLongInputs()36 public void testKnownLongInputs() { 37 assertHash(1669671676, murmur3_32().hashLong(0L)); 38 assertHash(-846261623, murmur3_32().hashLong(-42L)); 39 assertHash(1871679806, murmur3_32().hashLong(42L)); 40 assertHash(1366273829, murmur3_32().hashLong(Long.MIN_VALUE)); 41 assertHash(-2106506049, murmur3_32().hashLong(Long.MAX_VALUE)); 42 } 43 testKnownStringInputs()44 public void testKnownStringInputs() { 45 assertHash(0, murmur3_32().hashUnencodedChars("")); 46 assertHash(679745764, murmur3_32().hashUnencodedChars("k")); 47 assertHash(1510782915, murmur3_32().hashUnencodedChars("hell")); 48 assertHash(-675079799, murmur3_32().hashUnencodedChars("hello")); 49 assertHash(1935035788, murmur3_32().hashUnencodedChars("http://www.google.com/")); 50 assertHash( 51 -528633700, murmur3_32().hashUnencodedChars("The quick brown fox jumps over the lazy dog")); 52 } 53 testKnownUtf8StringInputs()54 public void testKnownUtf8StringInputs() { 55 assertHash(0, murmur3_32().hashString("", Charsets.UTF_8)); 56 assertHash(0xcfbda5d1, murmur3_32().hashString("k", Charsets.UTF_8)); 57 assertHash(0xa167dbf3, murmur3_32().hashString("hell", Charsets.UTF_8)); 58 assertHash(0x248bfa47, murmur3_32().hashString("hello", Charsets.UTF_8)); 59 assertHash(0x3d41b97c, murmur3_32().hashString("http://www.google.com/", Charsets.UTF_8)); 60 assertHash( 61 0x2e4ff723, 62 murmur3_32().hashString("The quick brown fox jumps over the lazy dog", Charsets.UTF_8)); 63 assertHash(0xfc5ba834, murmur3_32().hashString("毎月1日,毎週月曜日", Charsets.UTF_8)); 64 } 65 66 @SuppressWarnings("deprecation") testSimpleStringUtf8()67 public void testSimpleStringUtf8() { 68 assertEquals( 69 murmur3_32().hashBytes("ABCDefGHI\u0799".getBytes(Charsets.UTF_8)), 70 murmur3_32().hashString("ABCDefGHI\u0799", Charsets.UTF_8)); 71 } 72 73 @SuppressWarnings("deprecation") testStringInputsUtf8()74 public void testStringInputsUtf8() { 75 Random rng = new Random(0); 76 for (int z = 0; z < 100; z++) { 77 String str; 78 int[] codePoints = new int[rng.nextInt(8)]; 79 for (int i = 0; i < codePoints.length; i++) { 80 do { 81 codePoints[i] = rng.nextInt(0x800); 82 } while (!Character.isValidCodePoint(codePoints[i]) 83 || (codePoints[i] >= Character.MIN_SURROGATE 84 && codePoints[i] <= Character.MAX_SURROGATE)); 85 } 86 StringBuilder builder = new StringBuilder(); 87 for (int i = 0; i < codePoints.length; i++) { 88 builder.appendCodePoint(codePoints[i]); 89 } 90 str = builder.toString(); 91 assertEquals( 92 murmur3_32().hashBytes(str.getBytes(Charsets.UTF_8)), 93 murmur3_32().hashString(str, Charsets.UTF_8)); 94 } 95 } 96 assertHash(int expected, HashCode actual)97 private static void assertHash(int expected, HashCode actual) { 98 assertEquals(HashCode.fromInt(expected), actual); 99 } 100 testParanoidHashBytes()101 public void testParanoidHashBytes() { 102 HashFn hf = 103 new HashFn() { 104 @Override 105 public byte[] hash(byte[] input, int seed) { 106 return murmur3_32(seed).hashBytes(input).asBytes(); 107 } 108 }; 109 // Murmur3A, MurmurHash3 for x86, 32-bit (MurmurHash3_x86_32) 110 // https://github.com/aappleby/smhasher/blob/master/src/main.cpp 111 HashTestUtils.verifyHashFunction(hf, 32, 0xB0F57EE3); 112 } 113 testParanoid()114 public void testParanoid() { 115 HashFn hf = 116 new HashFn() { 117 @Override 118 public byte[] hash(byte[] input, int seed) { 119 Hasher hasher = murmur3_32(seed).newHasher(); 120 Funnels.byteArrayFunnel().funnel(input, hasher); 121 return hasher.hash().asBytes(); 122 } 123 }; 124 // Murmur3A, MurmurHash3 for x86, 32-bit (MurmurHash3_x86_32) 125 // https://github.com/aappleby/smhasher/blob/master/src/main.cpp 126 HashTestUtils.verifyHashFunction(hf, 32, 0xB0F57EE3); 127 } 128 testInvariants()129 public void testInvariants() { 130 HashTestUtils.assertInvariants(murmur3_32()); 131 } 132 133 @SuppressWarnings("deprecation") testInvalidUnicodeHashString()134 public void testInvalidUnicodeHashString() { 135 String str = 136 new String( 137 new char[] {'a', Character.MIN_HIGH_SURROGATE, Character.MIN_HIGH_SURROGATE, 'z'}); 138 assertEquals( 139 murmur3_32().hashBytes(str.getBytes(Charsets.UTF_8)), 140 murmur3_32().hashString(str, Charsets.UTF_8)); 141 } 142 testInvalidUnicodeHasherPutString()143 public void testInvalidUnicodeHasherPutString() { 144 String str = 145 new String( 146 new char[] {'a', Character.MIN_HIGH_SURROGATE, Character.MIN_HIGH_SURROGATE, 'z'}); 147 assertEquals( 148 murmur3_32().hashBytes(str.getBytes(Charsets.UTF_8)), 149 murmur3_32().newHasher().putString(str, Charsets.UTF_8).hash()); 150 } 151 } 152