This commit is contained in:
Looly 2024-03-18 16:09:48 +08:00
parent 0567a98e08
commit a34cb71bc0
8 changed files with 27 additions and 28 deletions

View File

@ -12,7 +12,6 @@
package org.dromara.hutool.core.codec; package org.dromara.hutool.core.codec;
import org.dromara.hutool.core.util.ByteUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.nio.ByteOrder; import java.nio.ByteOrder;
@ -43,10 +42,10 @@ public class Number128 extends Number implements Comparable<Number128>{
/** /**
* 构造 * 构造
* *
* @param leastSigBits 低位
* @param mostSigBits 高位 * @param mostSigBits 高位
* @param leastSigBits 低位
*/ */
public Number128(final long leastSigBits, final long mostSigBits) { public Number128(final long mostSigBits, final long leastSigBits) {
this.mostSigBits = mostSigBits; this.mostSigBits = mostSigBits;
this.leastSigBits = leastSigBits; this.leastSigBits = leastSigBits;
} }
@ -93,7 +92,7 @@ public class Number128 extends Number implements Comparable<Number128>{
* @return 高低位数组long[0]低位long[1]高位 * @return 高低位数组long[0]低位long[1]高位
*/ */
public long[] getLongArray() { public long[] getLongArray() {
return getLongArray(ByteUtil.DEFAULT_ORDER); return getLongArray(ByteOrder.BIG_ENDIAN);
} }
/** /**

View File

@ -215,9 +215,8 @@ public class CityHash implements Hash32<byte[]>, Hash64<byte[]>, Hash128<byte[]>
public Number128 hash128(final byte[] data) { public Number128 hash128(final byte[] data) {
final int len = data.length; final int len = data.length;
return len >= 16 ? return len >= 16 ?
hash128(data, 16, hash128(data, 16, new Number128(fetch64(data, 8) + k0, fetch64(data, 0))) :
new Number128(fetch64(data, 0), fetch64(data, 8) + k0)) : hash128(data, 0, new Number128(k1, k0));
hash128(data, 0, new Number128(k0, k1));
} }
/** /**
@ -301,8 +300,8 @@ public class CityHash implements Hash32<byte[]>, Hash64<byte[]>, Hash128<byte[]>
// different 56-byte-to-8-byte hashes to get a 16-byte final result. // different 56-byte-to-8-byte hashes to get a 16-byte final result.
x = hashLen16(x, v.getLeastSigBits()); x = hashLen16(x, v.getLeastSigBits());
y = hashLen16(y + z, w.getLeastSigBits()); y = hashLen16(y + z, w.getLeastSigBits());
return new Number128(hashLen16(x + v.getMostSigBits(), w.getMostSigBits()) + y, return new Number128(hashLen16(x + w.getMostSigBits(), y + v.getMostSigBits()),
hashLen16(x + w.getMostSigBits(), y + v.getMostSigBits())); hashLen16(x + v.getMostSigBits(), w.getMostSigBits()) + y);
} }
@ -421,7 +420,7 @@ public class CityHash implements Hash32<byte[]>, Hash64<byte[]>, Hash128<byte[]>
} }
private long hashLen16(final long u, final long v) { private long hashLen16(final long u, final long v) {
return hash128to64(new Number128(u, v)); return hash128to64(new Number128(v, u));
} }
private long hash128to64(final Number128 number128) { private long hash128to64(final Number128 number128) {
@ -466,7 +465,7 @@ public class CityHash implements Hash32<byte[]>, Hash64<byte[]>, Hash128<byte[]>
a += x; a += x;
a += y; a += y;
b += Long.rotateRight(a, 44); b += Long.rotateRight(a, 44);
return new Number128(a + z, b + c); return new Number128(b + c, a + z);
} }
// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
@ -509,7 +508,7 @@ public class CityHash implements Hash32<byte[]>, Hash64<byte[]>, Hash128<byte[]>
} }
a = hashLen16(a, c); a = hashLen16(a, c);
b = hashLen16(d, b); b = hashLen16(d, b);
return new Number128(a ^ b, hashLen16(b, a)); return new Number128(hashLen16(b, a), a ^ b);
} }
//------------------------------------------------------------------------------------------------------- Private method end //------------------------------------------------------------------------------------------------------- Private method end
} }

View File

@ -354,7 +354,7 @@ public class MurmurHash implements Hash32<byte[]>, Hash64<byte[]>, Hash128<byte[
h1 += h2; h1 += h2;
h2 += h1; h2 += h1;
return new Number128(h1, h2); return new Number128(h2, h1);
} }
private static int mix32(int k, int hash) { private static int mix32(int k, int hash) {

View File

@ -70,7 +70,7 @@ public class MetroHash128 extends AbstractMetroHash<MetroHash128> implements Has
* @return hash值 * @return hash值
*/ */
public Number128 get() { public Number128 get() {
return new Number128(v1, v0); return new Number128(v0, v1);
} }
@Override @Override

View File

@ -105,7 +105,7 @@ public class ULID implements Comparable<ULID>, Serializable {
// randomness[1]填充到16_bit_uint_random的低8位 // randomness[1]填充到16_bit_uint_random的低8位
msb |= randomness[0x1] & 0xff; msb |= randomness[0x1] & 0xff;
return new ULID(new Number128(ByteUtil.toLong(randomness, 2, ByteOrder.BIG_ENDIAN), msb)); return new ULID(new Number128(msb, ByteUtil.toLong(randomness, 2, ByteOrder.BIG_ENDIAN)));
} }
/** /**
@ -131,7 +131,7 @@ public class ULID implements Comparable<ULID>, Serializable {
final long most = (time << 16) | (part1 >>> 24); final long most = (time << 16) | (part1 >>> 24);
final long least = part2 | (part1 << 40); final long least = part2 | (part1 << 40);
return new ULID(new Number128(least, most)); return new ULID(new Number128(most, least));
} }
/** /**
@ -153,7 +153,7 @@ public class ULID implements Comparable<ULID>, Serializable {
for (int i = 8; i < 16; i++) { for (int i = 8; i < 16; i++) {
leastSignificantBits = (leastSignificantBits << 8) | (data[i] & 0xff); leastSignificantBits = (leastSignificantBits << 8) | (data[i] & 0xff);
} }
return new ULID(new Number128(leastSignificantBits, mostSignificantBits)); return new ULID(new Number128(mostSignificantBits, leastSignificantBits));
} }
// endregion // endregion
@ -226,7 +226,7 @@ public class ULID implements Comparable<ULID>, Serializable {
if (newLsb == OVERFLOW) { if (newLsb == OVERFLOW) {
newMsb += 1; newMsb += 1;
} }
return new ULID(new Number128(newLsb, newMsb)); return new ULID(new Number128(newMsb, newLsb));
} }
/** /**

View File

@ -95,7 +95,7 @@ public class UUID implements java.io.Serializable, Comparable<UUID> {
for (int i = 8; i < 16; i++) { for (int i = 8; i < 16; i++) {
lsb = (lsb << 8) | (data[i] & 0xff); lsb = (lsb << 8) | (data[i] & 0xff);
} }
this.idValue = new Number128(lsb, msb); this.idValue = new Number128(msb, lsb);
} }
/** /**
@ -105,7 +105,7 @@ public class UUID implements java.io.Serializable, Comparable<UUID> {
* @param leastSigBits 用于 {@code UUID} 的最低有效 64 * @param leastSigBits 用于 {@code UUID} 的最低有效 64
*/ */
public UUID(final long mostSigBits, final long leastSigBits) { public UUID(final long mostSigBits, final long leastSigBits) {
this.idValue = new Number128(leastSigBits, mostSigBits); this.idValue = new Number128(mostSigBits, leastSigBits);
} }
/** /**

View File

@ -15,6 +15,7 @@ package org.dromara.hutool.core.codec.hash.metro;
import org.dromara.hutool.core.codec.binary.HexUtil; import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.codec.Number128; import org.dromara.hutool.core.codec.Number128;
import org.dromara.hutool.core.util.ByteUtil; import org.dromara.hutool.core.util.ByteUtil;
import org.dromara.hutool.core.util.CharsetUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -130,4 +131,12 @@ public class MetroHash128Test {
private static String hex(final byte[] bytes){ private static String hex(final byte[] bytes){
return HexUtil.encodeStr(bytes).toUpperCase(); return HexUtil.encodeStr(bytes).toUpperCase();
} }
@Test
public void metroHash128GetLongArrayTest() {
final byte[] str = "我是一段测试123".getBytes(CharsetUtil.UTF_8);
final long[] hash128 = MetroHash128.of(0).hash128(str).getLongArray();
Assertions.assertEquals(228255164667538345L, hash128[0]);
Assertions.assertEquals(-6394585948993412256L, hash128[1]);
}
} }

View File

@ -49,14 +49,6 @@ public class MetroHashTest {
Assertions.assertEquals(147395857347476456L, hash64); Assertions.assertEquals(147395857347476456L, hash64);
} }
@Test
public void metroHash128Test() {
final byte[] str = "我是一段测试123".getBytes(CharsetUtil.UTF_8);
final long[] hash128 = MetroHash128.of(0).hash128(str).getLongArray();
Assertions.assertEquals(228255164667538345L, hash128[0]);
Assertions.assertEquals(-6394585948993412256L, hash128[1]);
}
/** /**
* 数据量越大 MetroHash 优势越明显 * 数据量越大 MetroHash 优势越明显
*/ */