public static int murmur3_32(int paramInt1, char[] paramArrayOfChar, int paramInt2, int paramInt3) {
/* 121 */ int i = paramInt1;
/* */
/* 123 */ int j = paramInt2;
/* 124 */ int k = paramInt3;
/* */
/* */ int m;
/* 127 */ while (k >= 2) {
/* 128 */ m = paramArrayOfChar[(j++)] & 0xFFFF | paramArrayOfChar[(j++)] << '\020';
/* */
/* 130 */ k -= 2;
/* */
/* 132 */ m *= -862048943;
/* 133 */ m = Integer.rotateLeft(m, 15);
/* 134 */ m *= 461845907;
/* */
/* 136 */ i ^= m;
/* 137 */ i = Integer.rotateLeft(i, 13);
/* 138 */ i = i * 5 + -430675100;
/* */ }
/* */
/* */
/* */
/* 143 */ if (k > 0) {
/* 144 */ m = paramArrayOfChar[j];
/* */
/* 146 */ m *= -862048943;
/* 147 */ m = Integer.rotateLeft(m, 15);
/* 148 */ m *= 461845907;
/* 149 */ i ^= m;
/* */ }
/* */
/* */
/* */
/* 154 */ i ^= paramInt3 * 2;
/* */
/* */
/* 157 */ i ^= i >>> 16;
/* 158 */ i *= -2048144789;
/* 159 */ i ^= i >>> 13;
/* 160 */ i *= -1028477387;
/* 161 */ i ^= i >>> 16;
/* */
/* 163 */ return i;
/* */ }
Nếu bạn thực sự tò mò muốn biết sau đó đi qua mã này có sẵn trong Hashing.class;
đây đầu tiên param HASHING_SEED được tính dựa trên mã dưới đây
{
long nanos = System.nanoTime();
long now = System.currentTimeMillis();
int SEED_MATERIAL[] = {
System.identityHashCode(String.class),
System.identityHashCode(System.class),
(int) (nanos >>> 32),
(int) nanos,
(int) (now >>> 32),
(int) now,
(int) (System.nanoTime() >>> 2)
};
// Use murmur3 to scramble the seeding material.
// Inline implementation to avoid loading classes
int h1 = 0;
// body
for (int k1 : SEED_MATERIAL) {
k1 *= 0xcc9e2d51;
k1 = (k1 << 15) | (k1 >>> 17);
k1 *= 0x1b873593;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1 = h1 * 5 + 0xe6546b64;
}
// tail (always empty, as body is always 32-bit chunks)
// finalization
h1 ^= SEED_MATERIAL.length * 4;
// finalization mix force all bits of a hash block to avalanche
h1 ^= h1 >>> 16;
h1 *= 0x85ebca6b;
h1 ^= h1 >>> 13;
h1 *= 0xc2b2ae35;
h1 ^= h1 >>> 16;
HASHING_SEED = h1;
}
các param thứ hai là mảng char của String, thứ ba luôn là '0' và một phần tư là char chiều dài mảng.
Và phép tính ở trên chỉ dành cho mã băm chuỗi.
Đối với tất cả các số nguyên, mã băm của nó sẽ là giá trị số nguyên của nó. Đối với char (tối đa hai chữ cái) nó sẽ là mã ASCII.
Nguồn
2017-05-25 18:37:49
Bất kỳ lý do cụ thể này đã được modded xuống? Nếu một cái gì đó ở đây là không chính xác, tôi sẽ yêu một sự điều chỉnh, nhưng để downvote mà không có lời giải thích thêm gì để thảo luận. – danben
Một vài năm trước, Ted Neward đã giải thích trong http://blogs.tedneward.com/2008/07/16/ObjecthashCode+Implementation.aspx cách OpenJDK đã triển khai Object.hashCode(). OpenJDK lấy mã băm từ địa chỉ đối tượng, nhưng lưu trữ giá trị này và trả về giá trị đó cho người gọi tiếp theo trong trường hợp đối tượng di chuyển trong bộ nhớ và thay đổi địa chỉ của nó. Sau khi xem xét ngắn gọn mã mới nhất, tôi thấy rằng việc triển khai dường như không thay đổi kể từ khi Neward viết bài viết của mình. –
Điều này dường như hỗ trợ câu trả lời của tôi. – danben