Java/Development Class/Hash Code
Содержание
- 1 A hash-code generator and a collection of static hash-code generation methods.
- 2 An implementation of the HMACT64 keyed hashing algorithm
- 3 A very efficient java hash algorithm, based on the BuzHash algoritm
- 4 Computing hash codes
- 5 Easy implementation of hashCode
- 6 Get hash code for primitive data types
- 7 Gets the hash code of an object returning zero when the object is null
- 8 Hash 32 String
- 9 Hash 64 String
- 10 Hash Code Builder
- 11 HashCode generation
- 12 MD5 hash generator
- 13 MD5 hashing: Encodes a string
- 14 MD5 String
- 15 Null Safe Hash Code
- 16 Return as hash code for the given object
- 17 Secure Hash
- 18 Unify Hash
A hash-code generator and a collection of static hash-code generation methods.
<source lang="java">
/*
* JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */
import java.io.Serializable; /**
* A hash-code generator and a collection of static hash-code generation * methods. * * @version $Revision: 2800 $ * @author */
@SuppressWarnings("unchecked") public final class HashCode implements Serializable, Cloneable, Comparable {
/** The serialVersionUID */ private static final long serialVersionUID = 2391396931740264021L; /** Hashcode for a "null" value. */ private static final int NULL_HASHCODE = 0; /** Hashcode for a "true" boolean */ private static final int TRUE_HASHCODE = 1231; // completely arbitrary /** Hashcode for a "false" boolean */ private static final int FALSE_HASHCODE = 1237; // completely arbitrary /** The hash-code value. */ private int value; /** * Construct a new HashCode using the given int as the * base value. * * @param value * int to use as the base value. */ public HashCode(final int value) { this.value = value; } /** * Construct a new HashCode. */ public HashCode() { this(0); } /** * Add the hash-code of the given value. * * @param b * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final boolean b) { value ^= generate(b); return this; } /** * Add the hash-code of the given value. * * @param n * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final byte n) { value ^= n; return this; } /** * Add the hash-code of the given value. * * @param n * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final char n) { value ^= n; return this; } /** * Add the hash-code of the given value. * * @param n * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final short n) { value ^= n; return this; } /** * Add the hash-code of the given value. * * @param n * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final int n) { value ^= n; return this; } /** * Add the hash-code of the given value. * * @param n * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final long n) { value ^= generate(n); return this; } /** * Add the hash-code of the given value. * * @param f * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final float f) { value ^= generate(f); return this; } /** * Add the hash-code of the given value. * * @param f * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final double f) { value ^= generate(f); return this; } /** * Add the hash-code of the given object. * * @param obj * Value to get hash-code from. * @return This HashCode. */ public HashCode add(final Object obj) { value ^= generate(obj); return this; } /** * Get the hash-code. * * @return Hash-code. */ public int hashCode() { return value; } /** * Compares this object with the specified int for order. * * @param other * Value to compare with. * @return A negative integer, zero, or a positive integer as this object is * less than, equal to, or greater than the specified object. */ public int compareTo(final int other) { return (value < other) ? -1 : (value == other) ? 0 : 1; } /** * Compares this object with the specified object for order. * * @param obj * Value to compare with. * @return A negative integer, zero, or a positive integer as this object is * less than, equal to, or greater than the specified object. * * @throws ClassCastException * Object is not a HashCode. */ public int compareTo(final Object obj) throws ClassCastException { HashCode hashCode = (HashCode) obj; return compareTo(hashCode.value); } /** * Test the equality of this HashCode and another object. * * @param obj * Object to test equality with. * @return True if object is equal. */ public boolean equals(final Object obj) { if (obj == this) return true; if (obj != null && obj.getClass() == getClass()) { return value == ((HashCode) obj).value; } return false; } /** * Return a string representation of this HashCode. * * @return A string representation of this HashCode. */ public String toString() { return String.valueOf(value); } /** * Return a cloned copy of this HashCode. * * @return Cloned HashCode. */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } // /////////////////////////////////////////////////////////////////////// // Generation Methods // // /////////////////////////////////////////////////////////////////////// /** * Generate a hash code for a boolean value. * * @param value * Boolean value to generate hash code from. * @return Hash code. */ public static int generate(final boolean value) { return value ? TRUE_HASHCODE : FALSE_HASHCODE; } /** * Generate a hash code for a long value. * * @param value * Long value to generate hash code from. * @return Hash code. */ public static int generate(final long value) { return (int) (value ^ (value >> 32)); } /** * Generate a hash code for a double value. * * @param value * Double value to generate hash code from. * @return Hash code. */ public static int generate(final double value) { return generate(Double.doubleToLongBits(value)); } /** * Generate a hash code for a float value. * * @param value * Float value to generate hash code from. * @return Hash code. */ public static int generate(final float value) { return Float.floatToIntBits(value); } /** * Generate a hash code for a byte array. * * @param bytes * An array of bytes to generate a hash code from. * @return Hash code. */ public static int generate(final byte[] bytes) { int hashcode = 0; for (int i = 0; i < bytes.length; i++) { hashcode <<= 1; hashcode ^= bytes[i]; } return hashcode; } /** * Generate a hash code for an object array. **
* Does not handle nested primitive array elements. * * @param array * Array to generate hashcode for. * @param deep * True to traverse elements which are arrays to determine the * elements hash code. * @return Hash code. */ public static int generate(final Object array[], final boolean deep) { int hashcode = 0; for (int i = 0; i < array.length; i++) { if (deep && (array[i] instanceof Object[])) { hashcode ^= generate((Object[]) array[i], true); } else { hashcode ^= array[i].hashCode(); } } return hashcode; } /** * Generate a shallow hash code for an object array. * * @param array * Array to generate hashcode for. * @return Hash code. */ public static int generate(final Object array[]) { return generate(array, false); } /** * Generate a hash code for an object. * * @param obj * Object to generate hashcode for. * @return Hash code. */ public static int generate(final Object obj) { if (obj != null) { return obj.hashCode(); } return NULL_HASHCODE; } } </source>
An implementation of the HMACT64 keyed hashing algorithm
<source lang="java">
/* HMACT64 keyed hashing algorithm
* Copyright (C) 2003 "Eric Glass" <jcifs at samba dot org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
import java.security.MessageDigest; /**
* This is an implementation of the HMACT64 keyed hashing algorithm. * HMACT64 is defined by Luke Leighton as a modified HMAC-MD5 (RFC 2104) * in which the key is truncated at 64 bytes (rather than being hashed * via MD5). */
public class HMACT64 extends MessageDigest implements Cloneable {
private static final int BLOCK_LENGTH = 64; private static final byte IPAD = (byte) 0x36; private static final byte OPAD = (byte) 0x5c; private MessageDigest md5; private byte[] ipad = new byte[BLOCK_LENGTH]; private byte[] opad = new byte[BLOCK_LENGTH]; /** * Creates an HMACT64 instance which uses the given secret key material. * * @param key The key material to use in hashing. */ public HMACT64(byte[] key) { super("HMACT64"); int length = Math.min(key.length, BLOCK_LENGTH); for (int i = 0; i < length; i++) { ipad[i] = (byte) (key[i] ^ IPAD); opad[i] = (byte) (key[i] ^ OPAD); } for (int i = length; i < BLOCK_LENGTH; i++) { ipad[i] = IPAD; opad[i] = OPAD; } try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception ex) { throw new IllegalStateException(ex.getMessage()); } engineReset(); } private HMACT64(HMACT64 hmac) throws CloneNotSupportedException { super("HMACT64"); this.ipad = hmac.ipad; this.opad = hmac.opad; this.md5 = (MessageDigest) hmac.md5.clone(); } public Object clone() { try { return new HMACT64(this); } catch (CloneNotSupportedException ex) { throw new IllegalStateException(ex.getMessage()); } } protected byte[] engineDigest() { byte[] digest = md5.digest(); md5.update(opad); return md5.digest(digest); } protected int engineDigest(byte[] buf, int offset, int len) { byte[] digest = md5.digest(); md5.update(opad); md5.update(digest); try { return md5.digest(buf, offset, len); } catch (Exception ex) { throw new IllegalStateException(); } } protected int engineGetDigestLength() { return md5.getDigestLength(); } protected void engineReset() { md5.reset(); md5.update(ipad); } protected void engineUpdate(byte b) { md5.update(b); } protected void engineUpdate(byte[] input, int offset, int len) { md5.update(input, offset, len); }
}
</source>
A very efficient java hash algorithm, based on the BuzHash algoritm
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/**
* A very efficient java hash algorithm, based on the BuzHash algoritm by Robert * Uzgalis (see http://www.serve.net/buz/hash.adt/java.000.html for more * information). BuzHash is Copyright (c)1996 Robert Uzgalis, All Rights * Reserved. Used with kind permission of the author * * @version $Id: HashUtil.java 587751 2007-10-24 02:41:36Z vgritsenko $ */
public final class HashUtil {
private static long initial_hash = 0xe12398c6d9ae3b8aL; // initial values private static long mix_master[/* 0:255 */] = { /* 000 */0x4476081a7043a46fL, 0x45768b8a6e7eac19L, 0xebd556c1cf055952L, /* */0x72ed2da1bf010101L, 0x3ff2030b128e8a64L, /* 005 */0xcbc330238adcfef2L, 0x737807fe42e20c6cL, 0x74dabaedb1095c58L, /* */0x968f065c65361d67L, 0xd3f4018ac7a4b199L, /* 010 */0x954b389b52f24df2L, 0x2f97a9d8d0549327L, 0xb9bea2b49a3b180fL, /* */0xaf2f42536b21f2ebL, 0x85d991663cff1325L, /* 015 */0xb9e1260207b575b9L, 0xf3ea88398a23b7e2L, 0xfaf8c83ffbd9091dL, /* */0x4274fe90834dbdf9L, 0x3f20b157b68d6313L, /* 020 */0x68b48972b6d06b93L, 0x694837b6eba548afL, 0xeecb51d1acc917c9L, /* */0xf1c633f02dffbcfaL, 0xa6549ec9d301f3b5L, /* 025 */0x451dc944f1663592L, 0x446d6acef6ce9e4fL, 0x1c8a5b3013206f02L, /* */0x5908ca36f2dc50f7L, 0x4fd55d3f3e880a87L, /* 030 */0xa03a8dbeabbf065dL, 0x3ccbbe078fabcb6dL, 0x1da53a259116f2d0L, /* */0xfb27a96fcb9af152L, 0x50aba242e85aec09L, /* 035 */0x24d4e414fc4fc987L, 0x83971844a9ce535eL, 0xc26a3fdeb849398eL, /* */0xc2380d044d2e70d8L, 0xab418aa8ae19b18fL, /* 040 */0xd95b6b9247d5ebeaL, 0x8b3b2171fdc60511L, 0xe15cd0ae3fcc44afL, /* */0x5a4e27f914a68f17L, 0x377bd28ca09aafdcL, /* 045 */0xbbeb9828594a3294L, 0x7c8df263ae1de1b9L, 0xba0a48a5fd1c1dd0L, /* */0x57cc1b8818b98ee6L, 0x8c570975d357dabcL, /* 050 */0x76bdcd6f2e8826aaL, 0x529b15b6ec4055f1L, 0x9147c7a54c34f8a9L, /* */0x2f96a7728170e402L, 0xe46602f455eca72eL, /* 055 */0x22834c4dd1bde03fL, 0x2644cf5a25e368ffL, 0x907c6de90b120f4aL, /* */0xadfe8ba99028f728L, 0xa85199ae14df0433L, /* 060 */0x2d749b946dd3601eL, 0x76e35457aa052772L, 0x90410bf6e427f736L, /* */0x536ad04d13e35041L, 0x8cc0d76769b76914L, /* 065 */0xae0249f6e3b3c01cL, 0x1bdfd075307d6fafL, 0xd8e04f70c221deccL, /* */0x4ab23622a4281a5dL, 0x37a5613da2fcaba7L, /* 070 */0x19a56203666d4a9fL, 0x158ffab502c4be93L, 0x0bee714e332ecb2fL, /* */0x69b71a59f6f74ab0L, 0x0fc7fc622f1dfe8fL, /* 075 */0x513966de7152a6f9L, 0xc16fae9cc2ea9be7L, 0xb66f0ac586c1899eL, /* */0x11e124aee3bdefd7L, 0x86cf5a577512901bL, /* 080 */0x33f33ba6994a1fbdL, 0xde6c4d1d3d47ff0dL, 0x6a99220dc6f78e66L, /* */0x2dc06ca93e2d25d2L, 0x96413b520134d573L, /* 085 */0xb4715ce8e1023afaL, 0xe6a75900c8c66c0aL, 0x6448f13ad54c12edL, /* */0xb9057c28cf6689f0L, 0xf4023daf67f7677aL, /* 090 */0x877c2650767b9867L, 0xb7ea587dcd5b2341L, 0xc048cf111733f9bcL, /* */0x112012c15bc867bfL, 0xc95f52b1d9418811L, /* 095 */0xa47e624ee7499083L, 0x26928606df9b12e8L, 0x5d020462ec3e0928L, /* */0x8bbde651f6d08914L, 0xd5db83db758e524aL, /* 100 */0x3105e355c000f455L, 0xdd7fe1b81a786c79L, 0x1f3a818c8e012db1L, /* */0xd902de819d7b42faL, 0x4200e63325cda5f0L, /* 105 */0x0e919cdc5fba9220L, 0x5360dd54605a11e1L, 0xa3182d0e6cb23e6cL, /* */0x13ee462c1b483b87L, 0x1b1b6087b997ee22L, /* 110 */0x81c36d0b877f7362L, 0xc24879932c1768d4L, 0x1faa756e1673f9adL, /* */0x61651b24d11fe93dL, 0x30fe3d9304e1cde4L, /* 115 */0x7be867c750747250L, 0x973e52c7005b5db6L, 0x75d6b699bbaf4817L, /* */0x25d2a9e97379e196L, 0xe65fb599aca98701L, /* 120 */0x6ac27960d24bde84L, 0xdfacc04c9fabbcb6L, 0xa46cd07f4a97882bL, /* */0x652031d8e59a1fd8L, 0x1185bd967ec7ce10L, /* 125 */0xfc9bd84c6780f244L, 0x0a0c59872f61b3ffL, 0x63885727a1c71c95L, /* */0x5e88b4390b2d765cL, 0xf0005ccaf988514dL, /* 130 */0x474e44280a98e840L, 0x32de151c1411bc42L, 0x2c4b86d5aa4482c2L, /* */0xccd93deb2d9d47daL, 0x3743236ff128a622L, /* 135 */0x42ed2f2635ba5647L, 0x99c74afd18962dbdL, 0x2d663bb870f6d242L, /* */0x7912033bc7635d81L, 0xb442862f43753680L, /* 140 */0x94b1a5400aeaab4cL, 0x5ce285fe810f2220L, 0xe8a7dbe565d9c0b1L, /* */0x219131af78356c94L, 0x7b3a80d130f27e2fL, /* 145 */0xbaa5d2859d16b440L, 0x821cfb6935771070L, 0xf68cfb6ee9bc2336L, /* */0x18244132e935d2fdL, 0x2ed0bda1f4720cffL, /* 150 */0x4ed48cdf6975173cL, 0xfd37a7a2520e2405L, 0x82c102b2a9e73ce2L, /* */0xadac6517062623a7L, 0x5a1294d318e26104L, /* 155 */0xea84fe65c0e4f061L, 0x4f96f8a9464cfee9L, 0x9831dff8ccdc534aL, /* */0x4ca927cd0f192a14L, 0x030900b294b71649L, /* 160 */0x644b263b9aeb0675L, 0xa601d4e34647e040L, 0x34d897eb397f1004L, /* */0xa6101c37f4ec8dfcL, 0xc29d2a8bbfd0006bL, /* 165 */0xc6b07df8c5b4ed0fL, 0xce1b7d92ba6bccbeL, 0xfa2f99442e03fe1bL, /* */0xd8863e4c16f0b363L, 0x033b2cccc3392942L, /* 170 */0x757dc33522d6cf9cL, 0xf07b1ff6ce55fec5L, 0x1569e75f09b40463L, /* */0xfa33fa08f14a310bL, 0x6eb79aa27bbcf76bL, /* 175 */0x157061207c249602L, 0x25e5a71fc4e99555L, 0x5df1fe93de625355L, /* */0x235b56090c1aa55dL, 0xe51068613eaced91L, /* 180 */0x45bd47b893b9ff1eL, 0x6595e1798d381f2dL, 0xc9b5848cbcdb5ba8L, /* */0x65985146ff7792bcL, 0x4ab4a17bf05a19a0L, /* 185 */0xfd94f4ca560ffb0cL, 0xcf9bad581a68fa68L, 0x92b4f0b502b1ce1aL, /* */0xbcbec0769a610474L, 0x8dbd31ded1a0fecbL, /* 190 */0xdd1f5ed9f90e8533L, 0x61c1e6a523f84d95L, 0xf24475f383c110c4L, /* */0xdb2dffa66f90588dL, 0xac06d88e9ee04455L, /* 195 */0xa215fc47c40504baL, 0x86d7caebfee93369L, 0x9eaec31985804099L, /* */0x0fba2214abe5d01bL, 0x5a32975a4b3865d6L, /* 200 */0x8cceebc98a5c108fL, 0x7e12c4589654f2dcL, 0xa49ad49fb0d19772L, /* */0x3d142dd9c406152bL, 0x9f13589e7be2b8a5L, /* 205 */0x5e8dbac1892967adL, 0xcc23b93a6308e597L, 0x1ef35f5fe874e16aL, /* */0x63ae9cc08d2e274fL, 0x5bbabee56007fc05L, /* 210 */0xabfd72994230fc39L, 0x9d71a13a99144de1L, 0xd9daf5aa8dcc89b3L, /* */0xe145ec0514161bfdL, 0x143befc2498cd270L, /* 215 */0xa8e192557dbbd9f8L, 0xcbeda2445628d7d0L, 0x997f0a93205d9ea4L, /* */0x01014a97f214ebfaL, 0x70c026ffd1ebedafL, /* 220 */0xf8737b1b3237002fL, 0x8afcbef3147e6e5eL, 0x0e1bb0684483ebd3L, /* */0x4cbad70ae9b05aa6L, 0xd4a31f523517c363L, /* 225 */0xdb0f057ae8e9e8a2L, 0x400894a919d89df6L, 0x6a626a9b62defab3L, /* */0xf907fd7e14f4e201L, 0xe10e4a5657c48f3fL, /* 230 */0xb17f9f54b8e6e5dcL, 0x6b9e69045fa6d27aL, 0x8b74b6a41dc3078eL, /* */0x027954d45ca367f9L, 0xd07207b8fdcbb7ccL, /* 235 */0xf397c47d2f36414bL, 0x05e4e8b11d3a034fL, 0x36adb3f7122d654fL, /* */0x607d9540eb336078L, 0xb639118e3a8b9600L, /* 240 */0xd0a406770b5f1484L, 0x3cbee8213ccfb7c6L, 0x467967bb2ff89cf1L, /* */0xb115fe29609919a6L, 0xba740e6ffa83287eL, /* 245 */0xb4e51be9b694b7cdL, 0xc9a081c677df5aeaL, 0x2e1fbcd8944508ccL, /* */0xf626e7895581fbb8L, 0x3ce6e9b5728a05cbL, /* 250 */0x46e87f2664a31712L, 0x8c1dc526c2f6acfaL, 0x7b4826726e560b10L, /* */0x2966e0099d8d7ce1L, 0xbb0dd5240d2b2adeL, 0x0d527cc60bbaa936L }; /** * This is buzhash the hash function on which most other Hash methods are * built. */ private static long buzhash(StringBuffer arg) { /* Hash StringBuffer */ long h = initial_hash; for (int i = 0; i < arg.length(); ++i) h = (h << 1) ^ (h >>> 63) ^ mix_master[(arg.charAt(i) ^ (arg.charAt(i) >>> 8)) & 0xff]; return h; } /** * This is buzhash the hash function on which most other Hash methods are * built. */ private static long buzhash(String arg) { /* Hash StringBuffer */ long h = initial_hash; for (int i = 0; i < arg.length(); ++i) h = (h << 1) ^ (h >>> 63) ^ mix_master[(arg.charAt(i) ^ (arg.charAt(i) >>> 8)) & 0xff]; return h; } /** * Hash a String. * * @param arg * The String to be hashed * @return The hash for the input. */ public static long hash(String arg) { // Make Hash from String return buzhash(arg); } /** * Hash a String. * * @param arg * The String represented by the StringBuffer to be hashed * @return The hash for the input. */ public static long hash(StringBuffer arg) { // Make Hash from StringBuffer return buzhash(arg); }
}
</source>
Computing hash codes
<source lang="java">
/*
* JBoss DNA (http://www.jboss.org/dna) * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * See the AUTHORS.txt file in the distribution for a full listing of * individual contributors. * * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA * is licensed to you under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * JBoss DNA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */
import java.util.Arrays; /**
* Utilities for easily computing hash codes. The algorithm should generally produce good distributions for use in hash-based * containers or collections, but as expected does always result in repeatable hash codes given the inputs. * @author Randall Hauch */
public class HashCode {
// Prime number used in improving distribution: 1,000,003 private static final int PRIME = 103; /** * Compute a combined hash code from the supplied objects. This method always returns 0 if no objects are supplied. * @param objects the objects that should be used to compute the hash code * @return the hash code */ public static int compute( Object... objects ) { return compute(0, objects); } /** * Compute a combined hash code from the supplied objects using the supplied seed. * @param seed a value upon which the hash code will be based; may be 0 * @param objects the objects that should be used to compute the hash code * @return the hash code */ protected static int compute( int seed, Object... objects ) { if (objects == null || objects.length == 0) { return seed * HashCode.PRIME; } // Compute the hash code for all of the objects ... int hc = seed; for (Object object : objects) { hc = HashCode.PRIME * hc; if (object instanceof byte[]) { hc += Arrays.hashCode((byte[])object); } else if (object instanceof boolean[]) { hc += Arrays.hashCode((boolean[])object); } else if (object instanceof short[]) { hc += Arrays.hashCode((short[])object); } else if (object instanceof int[]) { hc += Arrays.hashCode((int[])object); } else if (object instanceof long[]) { hc += Arrays.hashCode((long[])object); } else if (object instanceof float[]) { hc += Arrays.hashCode((float[])object); } else if (object instanceof double[]) { hc += Arrays.hashCode((double[])object); } else if (object instanceof char[]) { hc += Arrays.hashCode((char[])object); } else if (object instanceof Object[]) { hc += Arrays.hashCode((Object[])object); } else if (object != null) { hc += object.hashCode(); } } return hc; }
}
</source>
Easy implementation of hashCode
<source lang="java">
// Copyright (c) 2003-2009, Jodd Team (jodd.org). All Rights Reserved.
/**
* Collected methods which allow easy implementation of*hashCode()
. * Based on items #7 and #8 from "Effective Java" book. * <p> * Usage scenario:
* int result = HashCodeUtil.SEED; * result = HashCodeUtil.hash(result, fIsDecrepit); * ... * return result; *
*/
public class HashCode {
/** * An initial hash code value to which is added contributions from fields. * Using a non-zero value decreases collisions of hash code values. */ public static final int SEED = 173; public static final int PRIME = 37; // ---------------------------------------------------------------- boolean /** * Calculates hash code for booleans. */ public static int hash(int seed, boolean aBoolean) { return (PRIME * seed) + (aBoolean ? 1231 : 1237); } /** * Calculates hash code for boolean array. */ public static int hash(int seed, boolean[] booleanArray) { if (booleanArray == null) { return 0; } for (boolean aBoolean : booleanArray) { seed = hash(seed, aBoolean); } return seed; } /** * Calculates hash code for boolean array. */ public static int hashBooleanArray(int seed, boolean... booleanArray) { return hash(seed, booleanArray); } // ---------------------------------------------------------------- char /** * Calculates hash code for chars. */ public static int hash(int seed, char aChar) { return (PRIME * seed) + (int) aChar; } /** * Calculates hash code for char array. */ public static int hash(int seed, char[] charArray) { if (charArray == null) { return 0; } for (char aChar : charArray) { seed = hash(seed, aChar); } return seed; } /** * Calculates hash code for char array. */ public static int hashCharArray(int seed, char... charArray) { return hash(seed, charArray); } // ---------------------------------------------------------------- ints /** * Calculates hash code for ints. */ public static int hash(int seed, int anInt) { return (PRIME * seed) + anInt; } /** * Calculates hash code for int array. */ public static int hash(int seed, int[] intArray) { if (intArray == null) { return 0; } for (int anInt : intArray) { seed = hash(seed, anInt); } return seed; } /** * Calculates hash code for int array. */ public static int hashIntArray(int seed, int... intArray) { return hash(seed, intArray); }
/** * Calculates hash code for short array. */ public static int hash(int seed, short[] shortArray) { if (shortArray == null) { return 0; } for (short aShort : shortArray) { seed = hash(seed, aShort); } return seed; } /** * Calculates hash code for short array. */ public static int hashShortArray(int seed, short... shortArray) { return hash(seed, shortArray); } /** * Calculates hash code for byte array. */ public static int hash(int seed, byte[] byteArray) { if (byteArray == null) { return 0; } for (byte aByte : byteArray) { seed = hash(seed, aByte); } return seed; } /** * Calculates hash code for byte array. */ public static int hashByteArray(int seed, byte... byteArray) { return hash(seed, byteArray); }
// ---------------------------------------------------------------- long /** * Calculates hash code for longs. */ public static int hash(int seed, long aLong) { return (PRIME * seed) + (int) (aLong ^ (aLong >>> 32)); } /** * Calculates hash code for long array. */ public static int hash(int seed, long[] longArray) { if (longArray == null) { return 0; } for (long aLong : longArray) { seed = hash(seed, aLong); } return seed; } /** * Calculates hash code for long array. */ public static int hashLongArray(int seed, long... longArray) { return hash(seed, longArray); } // ---------------------------------------------------------------- float /** * Calculates hash code for floats. */ public static int hash(int seed, float aFloat) { return hash(seed, Float.floatToIntBits(aFloat)); } /** * Calculates hash code for float array. */ public static int hash(int seed, float[] floatArray) { if (floatArray == null) { return 0; } for (float aFloat : floatArray) { seed = hash(seed, aFloat); } return seed; }
/**
* Calculates hash code for float array.
*/
public static int hashFloatArray(int seed, float... floatArray) {
return hash(seed, floatArray);
}
// ---------------------------------------------------------------- double
/**
* Calculates hash code for doubles.
*/
public static int hash(int seed, double aDouble) {
return hash(seed, Double.doubleToLongBits(aDouble));
}
/**
* Calculates hash code for double array.
*/
public static int hash(int seed, double[] doubleArray) {
if (doubleArray == null) {
return 0;
}
for (double aDouble : doubleArray) {
seed = hash(seed, aDouble);
}
return seed;
}
/**
* Calculates hash code for double array.
*/
public static int hashDoubleArray(int seed, double... doubleArray) {
return hash(seed, doubleArray);
}
// ---------------------------------------------------------------- object
/**
* Calculates hash code for Objects. Object is a possibly-null object field, and possibly an array.
* <p>
* If aObject
is an array, then each element may be a primitive
* or a possibly-null object.
*/
public static int hash(int seed, Object aObject) {
int result = seed;
if (aObject == null) {
result = hash(result, 0);
} else if (aObject.getClass().isArray() == false) {
result = hash(result, aObject.hashCode());
} else {
Object[] objects = (Object[]) aObject;
int length = objects.length;
for (int idx = 0; idx < length; ++idx) {
result = hash(result, objects[idx]);
}
}
return result;
}
}
</source>
Get hash code for primitive data types
<source lang="java">
import java.lang.reflect.Array; import java.util.Arrays; /*
* Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
//Revised from springframework /**
* Miscellaneous object utility methods. Mainly for internal use within the * framework; consider Jakarta"s Commons Lang for a more comprehensive suite * of object utilities. * * @author Juergen Hoeller * @author Keith Donald * @author Rod Johnson * @author Rob Harrop * @author Alex Ruiz * @since 19.03.2004 * @see org.apache.rumons.lang.ObjectUtils */
abstract class ObjectUtils {
private static final int INITIAL_HASH = 7; private static final int MULTIPLIER = 31; private static final String EMPTY_STRING = ""; private static final String NULL_STRING = "null"; private static final String ARRAY_START = "{"; private static final String ARRAY_END = "}"; private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
/** * Return the same value as{@link Boolean#hashCode()}
. * @see Boolean#hashCode() */ public static int hashCode(boolean bool) { return bool ? 1231 : 1237; } /** * Return the same value as{@link Double#hashCode()}
. * @see Double#hashCode() */ public static int hashCode(double dbl) { long bits = Double.doubleToLongBits(dbl); return hashCode(bits); } /** * Return the same value as{@link Float#hashCode()}
. * @see Float#hashCode() */ public static int hashCode(float flt) { return Float.floatToIntBits(flt); } /** * Return the same value as{@link Long#hashCode()}
. * @see Long#hashCode() */ public static int hashCode(long lng) { return (int) (lng ^ (lng >>> 32)); }
}
</source>
Gets the hash code of an object returning zero when the object is null
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.io.Serializable; /**
* <p>Operations onObject
.
**
This class tries to handle null
input gracefully.
* An exception will generally not be thrown for a null
input.
* Each method documents its behaviour in more detail.
* * @author * @since 1.0 * @version $Id: ObjectUtils.java 594336 2007-11-12 22:54:02Z bayard $ */
public class ObjectUtils {
/***
Singleton used as a null
placeholder where
* null
has another meaning.
**
For example, in a HashMap
the
* {@link java.util.HashMap#get(java.lang.Object)} method returns
* null
if the Map
contains
* null
or if there is no matching key. The
* Null
placeholder can be used to distinguish between
* these two cases.
**
Another example is Hashtable
, where null
* cannot be stored.
**
This instance is Serializable.
*/ public static final Null NULL = new Null(); /***
ObjectUtils
instances should NOT be constructed in
* standard programming. Instead, the class should be used as
* ObjectUtils.defaultIfNull("a","b");
.
**
This constructor is public to permit tools that require a JavaBean instance * to operate.
*/ public ObjectUtils() { super(); } // Defaulting //----------------------------------------------------------------------- /***
Returns a default value if the object passed is
* null
.
**
* ObjectUtils.defaultIfNull(null, null) = null * ObjectUtils.defaultIfNull(null, "") = "" * ObjectUtils.defaultIfNull(null, "zz") = "zz" * ObjectUtils.defaultIfNull("abc", *) = "abc" * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE *
* * @param object the*Object
to test, may benull
* @param defaultValue the default value to return, may benull
* @returnobject
if it is notnull
, defaultValue otherwise */ public static Object defaultIfNull(Object object, Object defaultValue) { return object != null ? object : defaultValue; } /**
Compares two objects for equality, where either one or both
* objects may be null
.
**
* ObjectUtils.equals(null, null) = true * ObjectUtils.equals(null, "") = false * ObjectUtils.equals("", null) = false * ObjectUtils.equals("", "") = true * ObjectUtils.equals(Boolean.TRUE, null) = false * ObjectUtils.equals(Boolean.TRUE, "true") = false * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false *
* * @param object1 the first object, may be*null
* @param object2 the second object, may benull
* @returntrue
if the values of both objects are the same */ public static boolean equals(Object object1, Object object2) { if (object1 == object2) { return true; } if ((object1 == null) || (object2 == null)) { return false; } return object1.equals(object2); } /**
Gets the hash code of an object returning zero when the
* object is null
.
**
* ObjectUtils.hashCode(null) = 0 * ObjectUtils.hashCode(obj) = obj.hashCode() *
*
* @param obj the object to obtain the hash code of, may be null
* @return the hash code of the object, or zero if null
* @since 2.1
*/
public static int hashCode(Object obj) {
return (obj == null) ? 0 : obj.hashCode();
}
// Identity ToString
//-----------------------------------------------------------------------
/**
* Gets the toString that would be produced by Object
* if a class did not override toString itself. null
* will return null
.
**
* ObjectUtils.identityToString(null) = null * ObjectUtils.identityToString("") = "java.lang.String@1e23" * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa" *
* * @param object the object to create a toString for, may be **null
* @return the default toString text, ornull
if *null
passed in */ public static String identityToString(Object object) { if (object == null) { return null; } StringBuffer buffer = new StringBuffer(); identityToString(buffer, object); return buffer.toString(); } /**
Appends the toString that would be produced by Object
* if a class did not override toString itself. null
* will throw a NullPointerException for either of the two parameters.
**
* ObjectUtils.identityToString(buf, "") = buf.append("java.lang.String@1e23" * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa" * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa") *
* * @param buffer the buffer to append to * @param object the object to create a toString for * @since 2.4 */ public static void identityToString(StringBuffer buffer, Object object) { if (object == null) { throw new NullPointerException("Cannot get the toString of a null identity"); } buffer.append(object.getClass().getName()) .append("@") .append(Integer.toHexString(System.identityHashCode(object))); }
// ToString //----------------------------------------------------------------------- /***
Gets the toString
of an Object
returning
* an empty string ("") if null
input.
**
* ObjectUtils.toString(null) = "" * ObjectUtils.toString("") = "" * ObjectUtils.toString("bat") = "bat" * ObjectUtils.toString(Boolean.TRUE) = "true" *
* * @see StringUtils#defaultString(String) * @see String#valueOf(Object) * @param obj the Object to*toString
, may be null * @return the passed in Object"s toString, or nullStr ifnull
input * @since 2.0 */ public static String toString(Object obj) { return obj == null ? "" : obj.toString(); } /**
Gets the toString
of an Object
returning
* a specified text if null
input.
**
* ObjectUtils.toString(null, null) = null * ObjectUtils.toString(null, "null") = "null" * ObjectUtils.toString("", "null") = "" * ObjectUtils.toString("bat", "null") = "bat" * ObjectUtils.toString(Boolean.TRUE, "null") = "true" *
* * @see StringUtils#defaultString(String,String) * @see String#valueOf(Object) * @param obj the Object totoString
, may be null * @param nullStr the String to return ifnull
input, may be null * @return the passed in Object"s toString, or nullStr ifnull
input * @since 2.0 */ public static String toString(Object obj, String nullStr) { return obj == null ? nullStr : obj.toString(); }
// Null //----------------------------------------------------------------------- /***
Class used as a null placeholder where null
* has another meaning.
**
For example, in a HashMap
the
* {@link java.util.HashMap#get(java.lang.Object)} method returns
* null
if the Map
contains
* null
or if there is no matching key. The
* Null
placeholder can be used to distinguish between
* these two cases.
**
Another example is Hashtable
, where null
* cannot be stored.
*/ public static class Null implements Serializable { /** * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0 * * @see java.io.Serializable */ private static final long serialVersionUID = 7092611880189329093L; /** * Restricted constructor - singleton. */ Null() { super(); } /***
Ensure singleton.
* * @return the singleton value */ private Object readResolve() { return ObjectUtils.NULL; } }
}
</source>
Hash 32 String
<source lang="java">
/*
GNU LESSER GENERAL PUBLIC LICENSE Copyright (C) 2006 The Lobo Project This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Contact info: lobochief@users.sourceforge.net
- /
import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; public class Strings {
private static final MessageDigest MESSAGE_DIGEST; public static final String[] EMPTY_ARRAY = new String[0]; static { MessageDigest md; try { md = MessageDigest.getInstance("MD5"); } catch(NoSuchAlgorithmException err) { throw new IllegalStateException(); } MESSAGE_DIGEST = md; } private static final String HEX_CHARS = "0123456789ABCDEF"; public static String getMD5(String source) { byte[] bytes; try { bytes = source.getBytes("UTF-8"); } catch(java.io.UnsupportedEncodingException ue) { throw new IllegalStateException(ue); } byte[] result; synchronized(MESSAGE_DIGEST) { MESSAGE_DIGEST.update(bytes); result = MESSAGE_DIGEST.digest(); } char[] resChars = new char[32]; int len = result.length; for(int i = 0; i < len; i++) { byte b = result[i]; int lo4 = b & 0x0F; int hi4 = (b & 0xF0) >> 4; resChars[i*2] = HEX_CHARS.charAt(hi4); resChars[i*2 + 1] = HEX_CHARS.charAt(lo4); } return new String(resChars); } public static String getHash32(String source) throws UnsupportedEncodingException { String md5 = getMD5(source); return md5.substring(0, 8); } public static String getHash64(String source) throws UnsupportedEncodingException { String md5 = getMD5(source); return md5.substring(0, 16); }
}
</source>
Hash 64 String
<source lang="java">
/*
GNU LESSER GENERAL PUBLIC LICENSE Copyright (C) 2006 The Lobo Project This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Contact info: lobochief@users.sourceforge.net
- /
import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; public class Strings {
private static final MessageDigest MESSAGE_DIGEST; public static final String[] EMPTY_ARRAY = new String[0]; static { MessageDigest md; try { md = MessageDigest.getInstance("MD5"); } catch(NoSuchAlgorithmException err) { throw new IllegalStateException(); } MESSAGE_DIGEST = md; } private static final String HEX_CHARS = "0123456789ABCDEF"; public static String getMD5(String source) { byte[] bytes; try { bytes = source.getBytes("UTF-8"); } catch(java.io.UnsupportedEncodingException ue) { throw new IllegalStateException(ue); } byte[] result; synchronized(MESSAGE_DIGEST) { MESSAGE_DIGEST.update(bytes); result = MESSAGE_DIGEST.digest(); } char[] resChars = new char[32]; int len = result.length; for(int i = 0; i < len; i++) { byte b = result[i]; int lo4 = b & 0x0F; int hi4 = (b & 0xF0) >> 4; resChars[i*2] = HEX_CHARS.charAt(hi4); resChars[i*2 + 1] = HEX_CHARS.charAt(lo4); } return new String(resChars); } public static String getHash32(String source) throws UnsupportedEncodingException { String md5 = getMD5(source); return md5.substring(0, 8); } public static String getHash64(String source) throws UnsupportedEncodingException { String md5 = getMD5(source); return md5.substring(0, 16); }
}
</source>
Hash Code Builder
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.lang.reflect.Field; import java.lang.reflect.Modifier; /**
* HashCode
generation routines.
* * This class enables a good hashcode to be built for any class. It follows * the rules laid out in the book Effective Java, by Joshua Bloch. Writing a * good hashCode is actually quite difficult. This class aims to simplify the * process. * <p> * All relevant fields from the object should be included in the hashCode. Derived * fields may be excluded. In general, any field used in the equals method must be * used in the hashCode method. * <p> * To use this class write code as follows: *
* public class Person { * String name; * int age; * boolean isSmoker; * ... * * public int hashCode() { * // you pick a hard-coded, randomly chosen, non-zero, odd number * // ideally different for each class * return new HashCodeBuilder(17, 37). * append(name). * append(age). * append(smoker). * toHashCode(); * } * } *
* <p> * Alternatively, there is a method that uses reflection to determine * the fields to test. Because these fields are usually private, the method, **reflectionHashCode
, usesField.setAccessible
to * change the visibility of the fields. This will fail under a security manager, * unless the appropriate permissions are set. It is also slower than testing * explicitly. * <p> * A typical invocation for this method would look like:
* public boolean hashCode(Object o) { * return HashCodeBuilder.reflectionHashCode(this); * } *
* * @author * @version $Id: HashCodeBuilder.java 517121 2007-03-12 07:45:49Z ate $ */
public class HashCodeBuilder {
/** * Constant to use in building the hashCode */ private final int iConstant; /** * Running total of the hashCode */ private int iTotal = 0; /** * Constructor for HashCodeBuilder. * This constructor uses two hard coded choices for the constants needed * to build a hashCode. */ public HashCodeBuilder() { super(); iConstant = 37; iTotal = 17; } /** * Constructor for HashCodeBuilder. * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally * these should be different for each class, however this is not vital. * Prime numbers are preferred, especially for the multiplier. * * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier * @throws IllegalArgumentException if the number is zero or even */ public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) { super(); if (initialNonZeroOddNumber == 0) { throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value"); } if (initialNonZeroOddNumber % 2 == 0) { throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value"); } if (multiplierNonZeroOddNumber == 0) { throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier"); } if (multiplierNonZeroOddNumber % 2 == 0) { throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier"); } iConstant = multiplierNonZeroOddNumber; iTotal = initialNonZeroOddNumber; } //------------------------------------------------------------------------- /** * This method uses reflection to build a valid hash code. * <p> * It uses Field.setAccessible to gain access to private fields. This means * that it will throw a security exception if run under a security manger, if * the permissions are not set up. * It is also not as efficient as testing explicitly. * Transient members will be not be used, as they are likely derived * fields, and not part of the value of the object. * Static fields will not be tested. * This constructor uses two hard coded choices for the constants needed * to build a hash code. * * @param object the object to create a hash code for * @return int hash code * @throws IllegalArgumentException if the object is null */ public static int reflectionHashCode(Object object) { return reflectionHashCode(object, false); } /** * This method uses reflection to build a valid hash code. * <p> * It uses Field.setAccessible to gain access to private fields. This means * that it will throw a security exception if run under a security manger, if * the permissions are not set up. * It is also not as efficient as testing explicitly. * If the TestTransients parameter is set to true, transient members will be * tested, otherwise they are ignored, as they are likely derived fields, and * not part of the value of the object. * Static fields will not be tested. * This constructor uses two hard coded choices for the constants needed * to build a hash code. * * @param object the object to create a hash code for * @param testTransients whether to include transient fields * @return int hash code * @throws IllegalArgumentException if the object is null */ public static int reflectionHashCode(Object object, boolean testTransients) { return reflectionHashCode(17, 37, object, testTransients); } /** * This method uses reflection to build a valid hash code. * <p> * It uses Field.setAccessible to gain access to private fields. This means * that it will throw a security exception if run under a security manger, if * the permissions are not set up. * It is also not as efficient as testing explicitly. * Transient members will be not be used, as they are likely derived * fields, and not part of the value of the object. * Static fields will not be tested. * <p> * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally * these should be different for each class, however this is not vital. * Prime numbers are preferred, especially for the multiplier. * * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier * @param object the object to create a hash code for * @return int hash code * @throws IllegalArgumentException if the object is null * @throws IllegalArgumentException if the number is zero or even */ public static int reflectionHashCode(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object) { return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false); } /** * This method uses reflection to build a valid hash code. * <p> * It uses Field.setAccessible to gain access to private fields. This means * that it will throw a security exception if run under a security manger, if * the permissions are not set up. * It is also not as efficient as testing explicitly. * If the TestTransients parameter is set to true, transient members will be * tested, otherwise they are ignored, as they are likely derived fields, and * not part of the value of the object. * Static fields will not be tested. * <p> * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally * these should be different for each class, however this is not vital. * Prime numbers are preferred, especially for the multiplier. * * @param initialNonZeroOddNumber * @param multiplierNonZeroOddNumber * @param object the object to create a hash code for * @param testTransients whether to include transient fields * @return int hash code * @throws IllegalArgumentException if the object is null * @throws IllegalArgumentException if the number is zero or even */ public static int reflectionHashCode( int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object, boolean testTransients) { if (object == null) { throw new IllegalArgumentException("The object to build a hash code for must not be null"); } HashCodeBuilder hashCodeBuilder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber); Field[] fields = object.getClass().getDeclaredFields(); Field.setAccessible(fields, true); for (int i = 0; i < fields.length; ++i) { Field f = fields[i]; if (testTransients || !Modifier.isTransient(f.getModifiers())) { if (!Modifier.isStatic(f.getModifiers())) { try { hashCodeBuilder.append(f.get(object)); } catch (IllegalAccessException e) { //this can"t happen. Would get a Security exception instead //throw a runtime exception in case the impossible happens. throw new InternalError("Unexpected IllegalAccessException"); } } } } return hashCodeBuilder.toHashCode(); } //------------------------------------------------------------------------- /** * Append a hashCode for an Object. * * @param object the object to add to the hashCode * @return this */ public HashCodeBuilder append(Object object) { if (object == null) { iTotal = iTotal * iConstant; } else { if (object.getClass().isArray() == false) { //the simple case, not an array, just the element iTotal = iTotal * iConstant + object.hashCode(); } else { //"Switch" on type of array, to dispatch to the correct handler // This handles multi dimensional arrays if (object instanceof long[]) { append((long[]) object); } else if (object instanceof int[]) { append((int[]) object); } else if (object instanceof short[]) { append((short[]) object); } else if (object instanceof char[]) { append((char[]) object); } else if (object instanceof byte[]) { append((byte[]) object); } else if (object instanceof double[]) { append((double[]) object); } else if (object instanceof float[]) { append((float[]) object); } else if (object instanceof boolean[]) { append((boolean[]) object); } else { // Not an array of primitives append((Object[]) object); } } } return this; } /** * Append a hashCode for a long. * * @param value the long to add to the hashCode * @return this */ public HashCodeBuilder append(long value) { iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32))); return this; } /** * Append a hashCode for an int. * * @param value the int to add to the hashCode * @return this */ public HashCodeBuilder append(int value) { iTotal = iTotal * iConstant + value; return this; } /** * Append a hashCode for a short. * * @param value the short to add to the hashCode * @return this */ public HashCodeBuilder append(short value) { iTotal = iTotal * iConstant + value; return this; } /** * Append a hashCode for a char. * * @param value the char to add to the hashCode * @return this */ public HashCodeBuilder append(char value) { iTotal = iTotal * iConstant + value; return this; } /** * Append a hashCode for a byte. * * @param value the byte to add to the hashCode * @return this */ public HashCodeBuilder append(byte value) { iTotal = iTotal * iConstant + value; return this; } /** * Append a hashCode for a double. * * @param value the double to add to the hashCode * @return this */ public HashCodeBuilder append(double value) { return append(Double.doubleToLongBits(value)); } /** * Append a hashCode for a float. * * @param value the float to add to the hashCode * @return this */ public HashCodeBuilder append(float value) { iTotal = iTotal * iConstant + Float.floatToIntBits(value); return this; } /** * Append a hashCode for a long. * * @param value the long to add to the hashCode * @return this */ public HashCodeBuilder append(boolean value) { iTotal = iTotal * iConstant + (value ? 0 : 1); return this; } /** * Append a hashCode for an Object array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(Object[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a long array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(long[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for an int array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(int[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a short array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(short[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a char array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(char[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a byte array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(byte[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a double array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(double[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a float array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(float[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a boolean array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(boolean[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Return the computed hashCode * * @return int hashCode based on the fields appended */ public int toHashCode() { return iTotal; }
}
</source>
HashCode generation
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.lang.reflect.Field; import java.lang.reflect.Modifier; /**
* HashCode
generation routines.
* <p>
* This class enables a good hashcode to be built for any class. It follows
* the rules laid out in the book Effective Java, by Joshua Bloch. Writing a
* good hashCode is actually quite difficult. This class aims to simplify the
* process.
* <p>
* All relevant fields from the object should be included in the hashCode. Derived
* fields may be excluded. In general, any field used in the equals method must be
* used in the hashCode method.
* <p>
* To use this class write code as follows:
* * public class Person { * String name; * int age; * boolean isSmoker; * ... * * public int hashCode() { * // you pick a hard-coded, randomly chosen, non-zero, odd number * // ideally different for each class * return new HashCodeBuilder(17, 37). * append(name). * append(age). * append(smoker). * toHashCode(); * } * } *
* <p> * Alternatively, there is a method that uses reflection to determine * the fields to test. Because these fields are usually private, the method, **reflectionHashCode
, usesField.setAccessible
to * change the visibility of the fields. This will fail under a security manager, * unless the appropriate permissions are set. It is also slower than testing * explicitly. * <p> * A typical invocation for this method would look like:
* public boolean hashCode(Object o) { * return HashCodeBuilder.reflectionHashCode(this); * } *
* * @author * @version $Id: HashCodeBuilder.java 517121 2007-03-12 07:45:49Z ate $ */
public class HashCodeBuilder {
/** * Constant to use in building the hashCode */ private final int iConstant; /** * Running total of the hashCode */ private int iTotal = 0; /** * Constructor for HashCodeBuilder. * This constructor uses two hard coded choices for the constants needed * to build a hashCode. */ public HashCodeBuilder() { super(); iConstant = 37; iTotal = 17; } /** * Constructor for HashCodeBuilder. * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally * these should be different for each class, however this is not vital. * Prime numbers are preferred, especially for the multiplier. * * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier * @throws IllegalArgumentException if the number is zero or even */ public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) { super(); if (initialNonZeroOddNumber == 0) { throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value"); } if (initialNonZeroOddNumber % 2 == 0) { throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value"); } if (multiplierNonZeroOddNumber == 0) { throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier"); } if (multiplierNonZeroOddNumber % 2 == 0) { throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier"); } iConstant = multiplierNonZeroOddNumber; iTotal = initialNonZeroOddNumber; } //------------------------------------------------------------------------- /** * This method uses reflection to build a valid hash code. * <p> * It uses Field.setAccessible to gain access to private fields. This means * that it will throw a security exception if run under a security manger, if * the permissions are not set up. * It is also not as efficient as testing explicitly. * Transient members will be not be used, as they are likely derived * fields, and not part of the value of the object. * Static fields will not be tested. * This constructor uses two hard coded choices for the constants needed * to build a hash code. * * @param object the object to create a hash code for * @return int hash code * @throws IllegalArgumentException if the object is null */ public static int reflectionHashCode(Object object) { return reflectionHashCode(object, false); } /** * This method uses reflection to build a valid hash code. * <p> * It uses Field.setAccessible to gain access to private fields. This means * that it will throw a security exception if run under a security manger, if * the permissions are not set up. * It is also not as efficient as testing explicitly. * If the TestTransients parameter is set to true, transient members will be * tested, otherwise they are ignored, as they are likely derived fields, and * not part of the value of the object. * Static fields will not be tested. * This constructor uses two hard coded choices for the constants needed * to build a hash code. * * @param object the object to create a hash code for * @param testTransients whether to include transient fields * @return int hash code * @throws IllegalArgumentException if the object is null */ public static int reflectionHashCode(Object object, boolean testTransients) { return reflectionHashCode(17, 37, object, testTransients); } /** * This method uses reflection to build a valid hash code. * <p> * It uses Field.setAccessible to gain access to private fields. This means * that it will throw a security exception if run under a security manger, if * the permissions are not set up. * It is also not as efficient as testing explicitly. * Transient members will be not be used, as they are likely derived * fields, and not part of the value of the object. * Static fields will not be tested. * <p> * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally * these should be different for each class, however this is not vital. * Prime numbers are preferred, especially for the multiplier. * * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier * @param object the object to create a hash code for * @return int hash code * @throws IllegalArgumentException if the object is null * @throws IllegalArgumentException if the number is zero or even */ public static int reflectionHashCode(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object) { return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false); } /** * This method uses reflection to build a valid hash code. * <p> * It uses Field.setAccessible to gain access to private fields. This means * that it will throw a security exception if run under a security manger, if * the permissions are not set up. * It is also not as efficient as testing explicitly. * If the TestTransients parameter is set to true, transient members will be * tested, otherwise they are ignored, as they are likely derived fields, and * not part of the value of the object. * Static fields will not be tested. * <p> * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally * these should be different for each class, however this is not vital. * Prime numbers are preferred, especially for the multiplier. * * @param initialNonZeroOddNumber * @param multiplierNonZeroOddNumber * @param object the object to create a hash code for * @param testTransients whether to include transient fields * @return int hash code * @throws IllegalArgumentException if the object is null * @throws IllegalArgumentException if the number is zero or even */ public static int reflectionHashCode( int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object, boolean testTransients) { if (object == null) { throw new IllegalArgumentException("The object to build a hash code for must not be null"); } HashCodeBuilder hashCodeBuilder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber); Field[] fields = object.getClass().getDeclaredFields(); Field.setAccessible(fields, true); for (int i = 0; i < fields.length; ++i) { Field f = fields[i]; if (testTransients || !Modifier.isTransient(f.getModifiers())) { if (!Modifier.isStatic(f.getModifiers())) { try { hashCodeBuilder.append(f.get(object)); } catch (IllegalAccessException e) { //this can"t happen. Would get a Security exception instead //throw a runtime exception in case the impossible happens. throw new InternalError("Unexpected IllegalAccessException"); } } } } return hashCodeBuilder.toHashCode(); } //------------------------------------------------------------------------- /** * Append a hashCode for an Object. * * @param object the object to add to the hashCode * @return this */ public HashCodeBuilder append(Object object) { if (object == null) { iTotal = iTotal * iConstant; } else { if (object.getClass().isArray() == false) { //the simple case, not an array, just the element iTotal = iTotal * iConstant + object.hashCode(); } else { //"Switch" on type of array, to dispatch to the correct handler // This handles multi dimensional arrays if (object instanceof long[]) { append((long[]) object); } else if (object instanceof int[]) { append((int[]) object); } else if (object instanceof short[]) { append((short[]) object); } else if (object instanceof char[]) { append((char[]) object); } else if (object instanceof byte[]) { append((byte[]) object); } else if (object instanceof double[]) { append((double[]) object); } else if (object instanceof float[]) { append((float[]) object); } else if (object instanceof boolean[]) { append((boolean[]) object); } else { // Not an array of primitives append((Object[]) object); } } } return this; } /** * Append a hashCode for a long. * * @param value the long to add to the hashCode * @return this */ public HashCodeBuilder append(long value) { iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32))); return this; } /** * Append a hashCode for an int. * * @param value the int to add to the hashCode * @return this */ public HashCodeBuilder append(int value) { iTotal = iTotal * iConstant + value; return this; } /** * Append a hashCode for a short. * * @param value the short to add to the hashCode * @return this */ public HashCodeBuilder append(short value) { iTotal = iTotal * iConstant + value; return this; } /** * Append a hashCode for a char. * * @param value the char to add to the hashCode * @return this */ public HashCodeBuilder append(char value) { iTotal = iTotal * iConstant + value; return this; } /** * Append a hashCode for a byte. * * @param value the byte to add to the hashCode * @return this */ public HashCodeBuilder append(byte value) { iTotal = iTotal * iConstant + value; return this; } /** * Append a hashCode for a double. * * @param value the double to add to the hashCode * @return this */ public HashCodeBuilder append(double value) { return append(Double.doubleToLongBits(value)); } /** * Append a hashCode for a float. * * @param value the float to add to the hashCode * @return this */ public HashCodeBuilder append(float value) { iTotal = iTotal * iConstant + Float.floatToIntBits(value); return this; } /** * Append a hashCode for a long. * * @param value the long to add to the hashCode * @return this */ public HashCodeBuilder append(boolean value) { iTotal = iTotal * iConstant + (value ? 0 : 1); return this; } /** * Append a hashCode for an Object array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(Object[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a long array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(long[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for an int array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(int[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a short array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(short[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a char array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(char[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a byte array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(byte[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a double array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(double[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a float array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(float[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Append a hashCode for a boolean array. * * @param array the array to add to the hashCode * @return this */ public HashCodeBuilder append(boolean[] array) { if (array == null) { iTotal = iTotal * iConstant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } /** * Return the computed hashCode * * @return int hashCode based on the fields appended */ public int toHashCode() { return iTotal; }
}
</source>
MD5 hash generator
<source lang="java">
/*
* written Santeri Paavolainen, Helsinki Finland 1996 * (c) Santeri Paavolainen, Helsinki Finland 1996 * modifications Copyright (C) 2002-2007 Stephen Ostermiller * http://ostermiller.org/contact.pl?regarding=Java+Utilities * Copyright (C) 2007 Stu Thompson stu.rup -at- mailworks.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * See COPYING.TXT for details. * * The original work by Santeri Paavolainen can be found at * http://www.helsinki.fi/~sjpaavol/programs/md5/ * * This Java class has been derived from the RSA Data Security, Inc. MD5 * Message-Digest Algorithm and its reference implementation. */
import java.io.*; /**
* MD5 hash generator. * More information about this class is available from . * <p> * This class takes as input a message of arbitrary length and produces * as output a 128-bit "fingerprint" or "message digest" of the input. * It is conjectured that it is computationally infeasible to produce * two messages having the same message digest, or to produce any * message having a given pre-specified target message digest. The MD5 * algorithm is intended for digital signature applications, where a * large file must be "compressed" in a secure manner before being * encrypted with a private (secret) key under a public-key cryptosystem * such as RSA. * <p> * For more information see RFC1321. * * @see MD5OutputStream * @see MD5InputStream * * @author Santeri Paavolainen http://www.helsinki.fi/~sjpaavol/programs/md5/ * @author Stephen Ostermiller http://ostermiller.org/contact.pl?regarding=Java+Utilities * @since ostermillerutils 1.00.00 */
public class MD5 {
/** * Class constructor * * @since ostermillerutils 1.00.00 */ public MD5 () { reset(); } /** * Command line program that will take files as arguments * and output the MD5 sum for each file. * * @param args command line arguments * * @since ostermillerutils 1.00.00 */ public static void main (String[] args){ if (args.length == 0){ System.err.println("Please specify a file."); } else { for (String element: args) { try { System.out.println(MD5.getHashString(new File(element)) + " " + element); } catch (IOException x){ System.err.println(x.getMessage()); } } } } /** * Gets this hash sum as an array of 16 bytes. * * @return Array of 16 bytes, the hash of all updated bytes. * * @since ostermillerutils 1.00.00 */ public byte[] getHash() { if (!finalState.valid) { finalState.copy(workingState); long bitCount = finalState.bitCount; // Compute the number of left over bits int leftOver = (int) (((bitCount >>> 3)) & 0x3f); // Compute the amount of padding to add based on number of left over bits. int padlen = (leftOver < 56) ? (56 - leftOver) : (120 - leftOver); // add the padding update(finalState, padding, 0, padlen); // add the length (computed before padding was added) update(finalState, encode(bitCount), 0, 8); finalState.valid = true; } // make a copy of the hash before returning it. return encode(finalState.state, 16); } /** * Returns 32-character hex representation of this hash. * * @return String representation of this object"s hash. * * @since ostermillerutils 1.00.00 */ public String getHashString(){ return toHex(this.getHash()); } /** * Gets the MD5 hash of the given byte array. * * @param b byte array for which an MD5 hash is desired. * @return Array of 16 bytes, the hash of all updated bytes. * * @since ostermillerutils 1.00.00 */ public static byte[] getHash(byte[] b){ MD5 md5 = new MD5(); md5.update(b); return md5.getHash(); } /** * Gets the MD5 hash of the given byte array. * * @param b byte array for which an MD5 hash is desired. * @return 32-character hex representation the data"s MD5 hash. * * @since ostermillerutils 1.00.00 */ public static String getHashString(byte[] b){ MD5 md5 = new MD5(); md5.update(b); return md5.getHashString(); } /** * Gets the MD5 hash the data on the given InputStream. * * @param in byte array for which an MD5 hash is desired. * @return Array of 16 bytes, the hash of all updated bytes. * @throws IOException if an I/O error occurs. * * @since ostermillerutils 1.00.00 */ public static byte[] getHash(InputStream in) throws IOException { MD5 md5 = new MD5(); byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1){ md5.update(buffer, read); } return md5.getHash(); } /** * Gets the MD5 hash the data on the given InputStream. * * @param in byte array for which an MD5 hash is desired. * @return 32-character hex representation the data"s MD5 hash. * @throws IOException if an I/O error occurs. * * @since ostermillerutils 1.00.00 */ public static String getHashString(InputStream in) throws IOException { MD5 md5 = new MD5(); byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1){ md5.update(buffer, read); } return md5.getHashString(); } /** * Gets the MD5 hash of the given file. * * @param f file for which an MD5 hash is desired. * @return Array of 16 bytes, the hash of all updated bytes. * @throws IOException if an I/O error occurs. * * @since ostermillerutils 1.00.00 */ public static byte[] getHash(File f) throws IOException { InputStream is = new FileInputStream(f); byte[] hash = getHash(is); is.close(); return hash; } /** * Gets the MD5 hash of the given file. * * @param f file array for which an MD5 hash is desired. * @return 32-character hex representation the data"s MD5 hash. * @throws IOException if an I/O error occurs. * * @since ostermillerutils 1.00.00 */ public static String getHashString(File f) throws IOException { InputStream is = new FileInputStream(f); String hash = getHashString(is); is.close(); return hash; } /** * Gets the MD5 hash of the given String. * The string is converted to bytes using the current * platform"s default character encoding. * * @param s String for which an MD5 hash is desired. * @return Array of 16 bytes, the hash of all updated bytes. * * @since ostermillerutils 1.00.00 */ public static byte[] getHash(String s){ MD5 md5 = new MD5(); md5.update(s); return md5.getHash(); } /** * Gets the MD5 hash of the given String. * The string is converted to bytes using the current * platform"s default character encoding. * * @param s String for which an MD5 hash is desired. * @return 32-character hex representation the data"s MD5 hash. * * @since ostermillerutils 1.00.00 */ public static String getHashString(String s){ MD5 md5 = new MD5(); md5.update(s); return md5.getHashString(); }
/** * Gets the MD5 hash of the given String. * * @param s String for which an MD5 hash is desired. * @param enc The name of a supported character encoding. * @return Array of 16 bytes, the hash of all updated bytes. * @throws UnsupportedEncodingException If the named encoding is not supported. * * @since ostermillerutils 1.00.00 */ public static byte[] getHash(String s, String enc) throws UnsupportedEncodingException { MD5 md5 = new MD5(); md5.update(s, enc); return md5.getHash(); } /** * Gets the MD5 hash of the given String. * * @param s String for which an MD5 hash is desired. * @param enc The name of a supported character encoding. * @return 32-character hex representation the data"s MD5 hash. * @throws UnsupportedEncodingException If the named encoding is not supported. * * @since ostermillerutils 1.00.00 */ public static String getHashString(String s, String enc) throws UnsupportedEncodingException { MD5 md5 = new MD5(); md5.update(s, enc); return md5.getHashString(); }
/** * Reset the MD5 sum to its initial state. * * @since ostermillerutils 1.00.00 */ public void reset() { workingState.reset(); finalState.valid = false; } /** * Returns 32-character hex representation of this hash. * * @return String representation of this object"s hash. * * @since ostermillerutils 1.00.00 */ @Override public String toString(){ return getHashString(); } /** * Update this hash with the given data. * <p> * A state may be passed into this method so that we can add padding * and finalize a md5 hash without limiting our ability to update * more data later. * <p> * If length bytes are not available to be hashed, as many bytes as * possible will be hashed. * * @param state Which state is updated. * @param buffer Array of bytes to be hashed. * @param offset Offset to buffer array. * @param length number of bytes to hash. * * @since ostermillerutils 1.00.00 */ private void update (MD5State state, byte buffer[], int offset, int length) { finalState.valid = false; // if length goes beyond the end of the buffer, cut it short. if ((length + offset) > buffer.length){ length = buffer.length - offset; } // compute number of bytes mod 64 // this is what we have sitting in a buffer // that have not been hashed yet int index = (int) (state.bitCount >>> 3) & 0x3f; // add the length to the count (translate bytes to bits) state.bitCount += length << 3; int partlen = 64 - index; int i = 0; if (length >= partlen) { System.arraycopy(buffer, offset, state.buffer, index, partlen); transform(state, decode(state.buffer, 64, 0)); for (i = partlen; (i + 63) < length; i+= 64){ transform(state, decode(buffer, 64, i)); } index = 0; } // buffer remaining input if (i < length) { for (int start = i; i < length; i++) { state.buffer[index + i - start] = buffer[i + offset]; } } } /** * Update this hash with the given data. * <p> * If length bytes are not available to be hashed, as many bytes as * possible will be hashed. * * @param buffer Array of bytes to be hashed. * @param offset Offset to buffer array. * @param length number of bytes to hash. * * @since ostermillerutils 1.00.00 */ public void update (byte buffer[], int offset, int length) { update(workingState, buffer, offset, length); } /** * Update this hash with the given data. * <p> * If length bytes are not available to be hashed, as many bytes as * possible will be hashed. * * @param buffer Array of bytes to be hashed. * @param length number of bytes to hash. * * @since ostermillerutils 1.00.00 */ public void update (byte buffer[], int length) { update(buffer, 0, length); } /** * Update this hash with the given data. * * @param buffer Array of bytes to be hashed. * * @since ostermillerutils 1.00.00 */ public void update (byte buffer[]) { update(buffer, 0, buffer.length); } /** * Updates this hash with a single byte. * * @param b byte to be hashed. * * @since ostermillerutils 1.00.00 */ public void update (byte b) { byte buffer[] = new byte[1]; buffer[0] = b; update(buffer, 1); } /** * Update this hash with a String. * The string is converted to bytes using the current * platform"s default character encoding. * * @param s String to be hashed. * * @since ostermillerutils 1.00.00 */ public void update (String s) { update(s.getBytes()); } /** * Update this hash with a String. * * @param s String to be hashed. * @param enc The name of a supported character encoding. * @throws UnsupportedEncodingException If the named encoding is not supported. * * @since ostermillerutils 1.00.00 */ public void update (String s, String enc) throws UnsupportedEncodingException { update(s.getBytes(enc)); } /** * The current state from which the hash sum * can be computed or updated. * * @since ostermillerutils 1.00.00 */ private MD5State workingState = new MD5State(); /** * Cached copy of the final MD5 hash sum. This is created when * the hash is requested and it is invalidated when the hash * is updated. * * @since ostermillerutils 1.00.00 */ private MD5State finalState = new MD5State(); /** * Temporary buffer cached here for performance reasons. * * @since ostermillerutils 1.00.00 */ private int[] decodeBuffer = new int[16]; /** * 64 bytes of padding that can be added if the length * is not divisible by 64. * * @since ostermillerutils 1.00.00 */ private static final byte padding[] = { (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /** * Contains internal state of the MD5 class. * Passes MD5 test suite as defined in RFC1321. * * @since ostermillerutils 1.00.00 */ private class MD5State { /** * True if this state is valid. * * @since ostermillerutils 1.00.00 */ private boolean valid = true; /** * Reset to initial state. * * @since ostermillerutils 1.00.00 */ private void reset(){ state[0] = 0x67452301; state[1] = 0xefcdab89; state[2] = 0x98badcfe; state[3] = 0x10325476; bitCount = 0; } /** * 128-byte state * * @since ostermillerutils 1.00.00 */ private int state[] = new int[4]; /** * 64-bit count of the number of bits that have been hashed. * * @since ostermillerutils 1.00.00 */ private long bitCount; /** * 64-byte buffer (512 bits) for storing to-be-hashed characters * * @since ostermillerutils 1.00.00 */ private byte buffer[] = new byte[64]; private MD5State() { reset(); } /** * Set this state to be exactly the same as some other. * * @param from state to copy from. * * @since ostermillerutils 1.00.00 */ private void copy(MD5State from) { System.arraycopy(from.buffer, 0, this.buffer, 0, this.buffer.length); System.arraycopy(from.state, 0, this.state, 0, this.state.length); this.valid = from.valid; this.bitCount = from.bitCount; } }
/** * Turns array of bytes into string representing each byte as * a two digit unsigned hex number. * * @param hash Array of bytes to convert to hex-string * @return Generated hex string * * @since ostermillerutils 1.00.00 */ private static String toHex(byte hash[]){ StringBuffer buf = new StringBuffer(hash.length * 2); for (byte element: hash) { int intVal = element & 0xff; if (intVal < 0x10){ // append a zero before a one digit hex // number to make it two digits. buf.append("0"); } buf.append(Integer.toHexString(intVal)); } return buf.toString(); } private static int FF (int a, int b, int c, int d, int x, int s, int ac) { a += ((b & c) | (~b & d)); a += x; a += ac; //return rotateLeft(a, s) + b; a = (a << s) | (a >>> (32 - s)); return a + b; } private static int GG (int a, int b, int c, int d, int x, int s, int ac) { a += ((b & d) | (c & ~d)); a += x; a += ac; //return rotateLeft(a, s) + b; a = (a << s) | (a >>> (32 - s)); return a + b; } private static int HH (int a, int b, int c, int d, int x, int s, int ac) { a += (b ^ c ^ d); a += x; a += ac; //return rotateLeft(a, s) + b; a = (a << s) | (a >>> (32 - s)); return a + b; } private static int II (int a, int b, int c, int d, int x, int s, int ac) { a += (c ^ (b | ~d)); a += x; a += ac; //return rotateLeft(a, s) + b; a = (a << s) | (a >>> (32 - s)); return a + b; } private static byte[] encode(long l){ byte[] out = new byte[8]; out[0] = (byte) (l & 0xff); out[1] = (byte) ((l >>> 8) & 0xff); out[2] = (byte) ((l >>> 16) & 0xff); out[3] = (byte) ((l >>> 24) & 0xff); out[4] = (byte) ((l >>> 32) & 0xff); out[5] = (byte) ((l >>> 40) & 0xff); out[6] = (byte) ((l >>> 48) & 0xff); out[7] = (byte) ((l >>> 56) & 0xff); return out; } private static byte[] encode(int input[], int len){ byte[] out = new byte[len]; int i, j; for (i = j = 0; j < len; i++, j += 4) { out[j] = (byte) (input[i] & 0xff); out[j + 1] = (byte) ((input[i] >>> 8) & 0xff); out[j + 2] = (byte) ((input[i] >>> 16) & 0xff); out[j + 3] = (byte) ((input[i] >>> 24) & 0xff); } return out; } private int[] decode(byte buffer[], int len, int offset){ int i, j; for (i = j = 0; j < len; i++, j += 4) { decodeBuffer[i] = ( (buffer[j + offset] & 0xff)) | (((buffer[j + 1 + offset] & 0xff)) << 8) | (((buffer[j + 2 + offset] & 0xff)) << 16) | (((buffer[j + 3 + offset] & 0xff)) << 24 ); } return decodeBuffer; } private static void transform(MD5State state, int[] x){ int a = state.state[0]; int b = state.state[1]; int c = state.state[2]; int d = state.state[3]; /* Round 1 */ a = FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */ d = FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */ c = FF (c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */ b = FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */ a = FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */ d = FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */ c = FF (c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */ b = FF (b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */ a = FF (a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */ d = FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */ c = FF (c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */ b = FF (b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */ a = FF (a, b, c, d, x[12], 7, 0x6b901122); /* 13 */ d = FF (d, a, b, c, x[13], 12, 0xfd987193); /* 14 */ c = FF (c, d, a, b, x[14], 17, 0xa679438e); /* 15 */ b = FF (b, c, d, a, x[15], 22, 0x49b40821); /* 16 */ /* Round 2 */ a = GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */ d = GG (d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */ c = GG (c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */ b = GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */ a = GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */ d = GG (d, a, b, c, x[10], 9, 0x02441453); /* 22 */ c = GG (c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */ b = GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */ a = GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */ d = GG (d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */ c = GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */ b = GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */ a = GG (a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */ d = GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */ c = GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */ b = GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */ /* Round 3 */ a = HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */ d = HH (d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */ c = HH (c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */ b = HH (b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */ a = HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */ d = HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */ c = HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */ b = HH (b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */ a = HH (a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */ d = HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */ c = HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */ b = HH (b, c, d, a, x[ 6], 23, 0x04881d05); /* 44 */ a = HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */ d = HH (d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */ c = HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */ b = HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */ /* Round 4 */ a = II (a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */ d = II (d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */ c = II (c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */ b = II (b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */ a = II (a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */ d = II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */ c = II (c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */ b = II (b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */ a = II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */ d = II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */ c = II (c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */ b = II (b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */ a = II (a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */ d = II (d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */ c = II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */ b = II (b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */ state.state[0] += a; state.state[1] += b; state.state[2] += c; state.state[3] += d; }
}
</source>
MD5 hashing: Encodes a string
<source lang="java">
/*
* Copyright (c) JForum Team * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * 1) Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * 2) Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or * other materials provided with the distribution. * 3) Neither the name of "Rafael Steil" nor * the names of its contributors may be used to endorse * or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE * * This file creation date: Mar 29, 2003 / 1:15:50 AM * The JForum Project * http://www.jforum.net */
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
/**
* Encodes a string using MD5 hashing * * @author Rafael Steil * @version $Id: MD5.java,v 1.7 2006/08/23 02:13:44 rafaelsteil Exp $ */
public class MD5 {
/** * Encodes a string * * @param str String to encode * @return Encoded String * @throws NoSuchAlgorithmException */ public static String crypt(String str) { if (str == null || str.length() == 0) { throw new IllegalArgumentException("String to encript cannot be null or zero length"); } StringBuffer hexString = new StringBuffer(); try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(str.getBytes()); byte[] hash = md.digest(); for (int i = 0; i < hash.length; i++) { if ((0xff & hash[i]) < 0x10) { hexString.append("0" + Integer.toHexString((0xFF & hash[i]))); } else { hexString.append(Integer.toHexString(0xFF & hash[i])); } } } catch (NoSuchAlgorithmException e) { throw new RuntimeException("" + e); } return hexString.toString(); }
}
</source>
MD5 String
<source lang="java">
/*
GNU LESSER GENERAL PUBLIC LICENSE Copyright (C) 2006 The Lobo Project This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Contact info: lobochief@users.sourceforge.net
- /
import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; public class Strings {
private static final MessageDigest MESSAGE_DIGEST; public static final String[] EMPTY_ARRAY = new String[0]; static { MessageDigest md; try { md = MessageDigest.getInstance("MD5"); } catch(NoSuchAlgorithmException err) { throw new IllegalStateException(); } MESSAGE_DIGEST = md; } private static final String HEX_CHARS = "0123456789ABCDEF"; public static String getMD5(String source) { byte[] bytes; try { bytes = source.getBytes("UTF-8"); } catch(java.io.UnsupportedEncodingException ue) { throw new IllegalStateException(ue); } byte[] result; synchronized(MESSAGE_DIGEST) { MESSAGE_DIGEST.update(bytes); result = MESSAGE_DIGEST.digest(); } char[] resChars = new char[32]; int len = result.length; for(int i = 0; i < len; i++) { byte b = result[i]; int lo4 = b & 0x0F; int hi4 = (b & 0xF0) >> 4; resChars[i*2] = HEX_CHARS.charAt(hi4); resChars[i*2 + 1] = HEX_CHARS.charAt(lo4); } return new String(resChars); } public static String getHash32(String source) throws UnsupportedEncodingException { String md5 = getMD5(source); return md5.substring(0, 8); } public static String getHash64(String source) throws UnsupportedEncodingException { String md5 = getMD5(source); return md5.substring(0, 16); }
}
</source>
Null Safe Hash Code
<source lang="java">
import java.lang.reflect.Array; import java.util.Arrays; /*
* Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
//Revised from springframework /**
* Miscellaneous object utility methods. Mainly for internal use within the * framework; consider Jakarta"s Commons Lang for a more comprehensive suite * of object utilities. * * @author Juergen Hoeller * @author Keith Donald * @author Rod Johnson * @author Rob Harrop * @author Alex Ruiz * @since 19.03.2004 * @see org.apache.rumons.lang.ObjectUtils */
abstract class ObjectUtils {
private static final int INITIAL_HASH = 7; private static final int MULTIPLIER = 31; private static final String EMPTY_STRING = ""; private static final String NULL_STRING = "null"; private static final String ARRAY_START = "{"; private static final String ARRAY_END = "}"; private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
/** * Return a hash code based on the contents of the specified array. * Ifarray
isnull
, this method returns 0. */ public static int nullSafeHashCode(boolean[] array) { if (array == null) { return 0; } int hash = INITIAL_HASH; int arraySize = array.length; for (int i = 0; i < arraySize; i++) { hash = MULTIPLIER * hash + hashCode(array[i]); } return hash; } /** * Return a hash code based on the contents of the specified array. * Ifarray
isnull
, this method returns 0. */ public static int nullSafeHashCode(byte[] array) { if (array == null) { return 0; } int hash = INITIAL_HASH; int arraySize = array.length; for (int i = 0; i < arraySize; i++) { hash = MULTIPLIER * hash + array[i]; } return hash; } /** * Return a hash code based on the contents of the specified array. * Ifarray
isnull
, this method returns 0. */ public static int nullSafeHashCode(char[] array) { if (array == null) { return 0; } int hash = INITIAL_HASH; int arraySize = array.length; for (int i = 0; i < arraySize; i++) { hash = MULTIPLIER * hash + array[i]; } return hash; } /** * Return a hash code based on the contents of the specified array. * Ifarray
isnull
, this method returns 0. */ public static int nullSafeHashCode(double[] array) { if (array == null) { return 0; } int hash = INITIAL_HASH; int arraySize = array.length; for (int i = 0; i < arraySize; i++) { hash = MULTIPLIER * hash + hashCode(array[i]); } return hash; } /** * Return a hash code based on the contents of the specified array. * Ifarray
isnull
, this method returns 0. */ public static int nullSafeHashCode(float[] array) { if (array == null) { return 0; } int hash = INITIAL_HASH; int arraySize = array.length; for (int i = 0; i < arraySize; i++) { hash = MULTIPLIER * hash + hashCode(array[i]); } return hash; } /** * Return a hash code based on the contents of the specified array. * Ifarray
isnull
, this method returns 0. */ public static int nullSafeHashCode(int[] array) { if (array == null) { return 0; } int hash = INITIAL_HASH; int arraySize = array.length; for (int i = 0; i < arraySize; i++) { hash = MULTIPLIER * hash + array[i]; } return hash; } /** * Return a hash code based on the contents of the specified array. * Ifarray
isnull
, this method returns 0. */ public static int nullSafeHashCode(long[] array) { if (array == null) { return 0; } int hash = INITIAL_HASH; int arraySize = array.length; for (int i = 0; i < arraySize; i++) { hash = MULTIPLIER * hash + hashCode(array[i]); } return hash; } /** * Return a hash code based on the contents of the specified array. * Ifarray
isnull
, this method returns 0. */ public static int nullSafeHashCode(short[] array) { if (array == null) { return 0; } int hash = INITIAL_HASH; int arraySize = array.length; for (int i = 0; i < arraySize; i++) { hash = MULTIPLIER * hash + array[i]; } return hash; } /** * Return the same value as{@link Boolean#hashCode()}
. * @see Boolean#hashCode() */ public static int hashCode(boolean bool) { return bool ? 1231 : 1237; } /** * Return the same value as{@link Double#hashCode()}
. * @see Double#hashCode() */ public static int hashCode(double dbl) { long bits = Double.doubleToLongBits(dbl); return hashCode(bits); } /** * Return the same value as{@link Float#hashCode()}
. * @see Float#hashCode() */ public static int hashCode(float flt) { return Float.floatToIntBits(flt); } /** * Return the same value as{@link Long#hashCode()}
. * @see Long#hashCode() */ public static int hashCode(long lng) { return (int) (lng ^ (lng >>> 32)); }
}
</source>
Return as hash code for the given object
<source lang="java">
import java.lang.reflect.Array; import java.util.Arrays; /*
* Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
//Revised from springframework /**
* Miscellaneous object utility methods. Mainly for internal use within the * framework; consider Jakarta"s Commons Lang for a more comprehensive suite * of object utilities. * * @author Juergen Hoeller * @author Keith Donald * @author Rod Johnson * @author Rob Harrop * @author Alex Ruiz * @since 19.03.2004 * @see org.apache.rumons.lang.ObjectUtils */
abstract class ObjectUtils {
private static final int INITIAL_HASH = 7; private static final int MULTIPLIER = 31; private static final String EMPTY_STRING = ""; private static final String NULL_STRING = "null"; private static final String ARRAY_START = "{"; private static final String ARRAY_END = "}"; private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; private static final String ARRAY_ELEMENT_SEPARATOR = ", "; /** * Return as hash code for the given object; typically the value of *{@link Object#hashCode()}
. If the object is an array, * this method will delegate to any of thenullSafeHashCode
* methods for arrays in this class. If the object isnull
, * this method returns 0. * @see #nullSafeHashCode(Object[]) * @see #nullSafeHashCode(boolean[]) * @see #nullSafeHashCode(byte[]) * @see #nullSafeHashCode(char[]) * @see #nullSafeHashCode(double[]) * @see #nullSafeHashCode(float[]) * @see #nullSafeHashCode(int[]) * @see #nullSafeHashCode(long[]) * @see #nullSafeHashCode(short[]) */ public static int nullSafeHashCode(Object obj) { if (obj == null) { return 0; } if (obj instanceof Object[]) { return nullSafeHashCode((Object[]) obj); } if (obj instanceof boolean[]) { return nullSafeHashCode((boolean[]) obj); } if (obj instanceof byte[]) { return nullSafeHashCode((byte[]) obj); } if (obj instanceof char[]) { return nullSafeHashCode((char[]) obj); } if (obj instanceof double[]) { return nullSafeHashCode((double[]) obj); } if (obj instanceof float[]) { return nullSafeHashCode((float[]) obj); } if (obj instanceof int[]) { return nullSafeHashCode((int[]) obj); } if (obj instanceof long[]) { return nullSafeHashCode((long[]) obj); } if (obj instanceof short[]) { return nullSafeHashCode((short[]) obj); } return obj.hashCode(); }
}
</source>
Secure Hash
<source lang="java">
/*
* JBoss DNA (http://www.jboss.org/dna) * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * See the AUTHORS.txt file in the distribution for a full listing of * individual contributors. * * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA * is licensed to you under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * JBoss DNA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /**
* @author Randall Hauch */
public class SecureHash {
/** * Commonly-used hashing algorithms. */ public enum Algorithm { MD2("MD2", "The MD2 message digest algorithm as defined in RFC 1319"), MD5("MD5", "The MD5 message digest algorithm as defined in RFC 1321"), SHA_1("SHA-1", "The Secure Hash Algorithm, as defined in Secure Hash Standard, NIST FIPS 180-1"), SHA_256( "SHA-256", "New hash algorithms for which the draft Federal Information Processing Standard 180-2, " + "Secure Hash Standard (SHS) is now available. SHA-256 is a 256-bit hash function intended to provide 128 bits of " + "security against collision attacks."), SHA_384( "SHA-384", "New hash algorithms for which the draft Federal Information Processing Standard 180-2, " + "Secure Hash Standard (SHS) is now available. A 384-bit hash may be obtained by truncating the SHA-512 output."), SHA_512( "SHA-512", "New hash algorithms for which the draft Federal Information Processing Standard 180-2, " + "Secure Hash Standard (SHS) is now available. SHA-512 is a 512-bit hash function intended to provide 256 bits of security."); private String name; private String description; private Algorithm( String name, String description ) { this.name = name; this.description = description; } public String digestName() { return this.name; } public String description() { return this.description; } @Override public String toString() { return digestName(); } } /** * Get the hash of the supplied content, using the supplied digest algorithm. * * @param algorithm the hashing function algorithm that should be used * @param content the content to be hashed; may not be null * @return the hash of the contents as a byte array * @throws NoSuchAlgorithmException if the supplied algorithm could not be found * @throws IllegalArgumentException if the algorithm is null */ public static byte[] getHash( Algorithm algorithm, byte[] content ) throws NoSuchAlgorithmException { return getHash(algorithm.digestName(), content); } /** * Get the hash of the supplied content, using the supplied digest algorithm. * * @param algorithm the hashing function algorithm that should be used * @param file the file containing the content to be hashed; may not be null * @return the hash of the contents as a byte array * @throws NoSuchAlgorithmException if the supplied algorithm could not be found * @throws IllegalArgumentException if the algorithm is null * @throws IOException if there is an error reading the file */ public static byte[] getHash( Algorithm algorithm, File file ) throws NoSuchAlgorithmException, IOException { return getHash(algorithm.digestName(), file); } /** * Get the hash of the supplied content, using the supplied digest algorithm. * * @param algorithm the hashing function algorithm that should be used * @param stream the stream containing the content to be hashed; may not be null * @return the hash of the contents as a byte array * @throws NoSuchAlgorithmException if the supplied algorithm could not be found * @throws IllegalArgumentException if the algorithm is null * @throws IOException if there is an error reading the stream */ public static byte[] getHash( Algorithm algorithm, InputStream stream ) throws NoSuchAlgorithmException, IOException { return getHash(algorithm.digestName(), stream); } /** * Get the hash of the supplied content, using the digest identified by the supplied name. * * @param digestName the name of the hashing function (or {@link MessageDigest message digest}) that should be used * @param content the content to be hashed; may not be null * @return the hash of the contents as a byte array * @throws NoSuchAlgorithmException if the supplied algorithm could not be found */ public static byte[] getHash( String digestName, byte[] content ) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance(digestName); assert digest != null; return digest.digest(content); } /** * Get the hash of the supplied content, using the digest identified by the supplied name. * * @param digestName the name of the hashing function (or {@link MessageDigest message digest}) that should be used * @param file the file whose content is to be hashed; may not be null * @return the hash of the contents as a byte array * @throws NoSuchAlgorithmException if the supplied algorithm could not be found * @throws IOException if there is an error reading the file */ public static byte[] getHash( String digestName, File file ) throws NoSuchAlgorithmException, IOException { MessageDigest digest = MessageDigest.getInstance(digestName); assert digest != null; InputStream in = new BufferedInputStream(new FileInputStream(file)); boolean error = false; try { int bufSize = 1024; byte[] buffer = new byte[bufSize]; int n = in.read(buffer, 0, bufSize); int count = 0; while (n != -1) { count += n; digest.update(buffer, 0, n); n = in.read(buffer, 0, bufSize); } } catch (IOException e) { error = true; throw e; } finally { try { in.close(); } catch (IOException e) { if (!error) throw e; } } return digest.digest(); } /** * Get the hash of the supplied content, using the digest identified by the supplied name. Note that this method never closes * the supplied stream. * * @param digestName the name of the hashing function (or {@link MessageDigest message digest}) that should be used * @param stream the stream containing the content to be hashed; may not be null * @return the hash of the contents as a byte array * @throws NoSuchAlgorithmException if the supplied algorithm could not be found * @throws IOException if there is an error reading the stream */ public static byte[] getHash( String digestName, InputStream stream ) throws NoSuchAlgorithmException, IOException { MessageDigest digest = MessageDigest.getInstance(digestName); assert digest != null; int bufSize = 1024; byte[] buffer = new byte[bufSize]; int n = stream.read(buffer, 0, bufSize); int count = 0; while (n != -1) { count += n; digest.update(buffer, 0, n); n = stream.read(buffer, 0, bufSize); } return digest.digest(); }
}
</source>
Unify Hash
<source lang="java">
/* UnifyHash Copyright (C) 1999-2002 Jochen Hoenicke.
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; see the file COPYING.LESSER. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: UnifyHash.java.in,v 1.3.2.2 2002/05/28 17:34:24 hoenicke Exp $ */
///#ifdef JDK12 import java.lang.ref.WeakReference; import java.lang.ref.ReferenceQueue; ///#endif import java.util.ruparator; import java.util.AbstractCollection; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.ConcurrentModificationException; import java.lang.UnsupportedOperationException; public class UnifyHash extends AbstractCollection {
/** * the default capacity */ private static final int DEFAULT_CAPACITY = 11; /** the default load factor of a HashMap */ private static final float DEFAULT_LOAD_FACTOR = 0.75F;
///#ifdef JDK12
private ReferenceQueue queue = new ReferenceQueue();
///#endif
static class Bucket
///#ifdef JDK12
extends WeakReference
///#endif
{
///#ifdef JDK12
public Bucket(Object o, ReferenceQueue q) { super(o, q); }
///#else /// public Bucket(Object o) { /// this.obj = o; /// } /// /// Object obj; /// /// public Object get() { /// return obj; /// } ///#endif
int hash; Bucket next; } private Bucket[] buckets; int modCount = 0; int size = 0; int threshold; float loadFactor; public UnifyHash(int initialCapacity, float loadFactor) { this.loadFactor = loadFactor; buckets = new Bucket[initialCapacity]; threshold = (int) (loadFactor * initialCapacity); } public UnifyHash(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } public UnifyHash() { this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); } private void grow() { Bucket[] oldBuckets = buckets; int newCap = buckets.length * 2 + 1; threshold = (int) (loadFactor * newCap); buckets = new Bucket[newCap]; for (int i = 0; i < oldBuckets.length; i++) { Bucket nextBucket; for (Bucket b = oldBuckets[i]; b != null; b = nextBucket) { if (i != Math.abs(b.hash % oldBuckets.length)) throw new RuntimeException(""+i+", hash: "+b.hash+", oldlength: "+oldBuckets.length); int newSlot = Math.abs(b.hash % newCap); nextBucket = b.next; b.next = buckets[newSlot]; buckets[newSlot] = b; } } }
///#ifdef JDK12
public final void cleanUp() { Bucket died; while ((died = (Bucket)queue.poll()) != null) { int diedSlot = Math.abs(died.hash % buckets.length); if (buckets[diedSlot] == died) buckets[diedSlot] = died.next; else { Bucket b = buckets[diedSlot]; while (b.next != died) b = b.next; b.next = died.next; } size--; } }
///#endif
public int size() { return size; } public Iterator iterator() {
///#ifdef JDK12
cleanUp();
///#endif
return new Iterator() { private int bucket = 0; private int known = modCount; private Bucket nextBucket; private Object nextVal; { internalNext(); } private void internalNext() { while (true) { while (nextBucket == null) { if (bucket == buckets.length) return; nextBucket = buckets[bucket++]; } nextVal = nextBucket.get(); if (nextVal != null) return; nextBucket = nextBucket.next; } } public boolean hasNext() { return nextBucket != null; } public Object next() { if (known != modCount) throw new ConcurrentModificationException(); if (nextBucket == null) throw new NoSuchElementException(); Object result = nextVal; nextBucket = nextBucket.next; internalNext(); return result; } public void remove() { throw new UnsupportedOperationException(); } }; } public Iterator iterateHashCode(final int hash) {
///#ifdef JDK12
cleanUp();
///#endif
return new Iterator() { private int known = modCount; private Bucket nextBucket = buckets[Math.abs(hash % buckets.length)]; private Object nextVal; { internalNext(); } private void internalNext() { while (nextBucket != null) { if (nextBucket.hash == hash) { nextVal = nextBucket.get(); if (nextVal != null) return; } nextBucket = nextBucket.next; } } public boolean hasNext() { return nextBucket != null; } public Object next() { if (known != modCount) throw new ConcurrentModificationException(); if (nextBucket == null) throw new NoSuchElementException(); Object result = nextVal; nextBucket = nextBucket.next; internalNext(); return result; } public void remove() { throw new UnsupportedOperationException(); } }; } public void put(int hash, Object o) { if (size++ > threshold) grow(); modCount++; int slot = Math.abs(hash % buckets.length);
///#ifdef JDK12
Bucket b = new Bucket(o, queue);
///#else /// Bucket b = new Bucket(o); ///#endif
b.hash = hash; b.next = buckets[slot]; buckets[slot] = b; } public Object unify(Object o, int hash, Comparator comparator) {
///#ifdef JDK12
cleanUp();
///#endif
int slot = Math.abs(hash % buckets.length); for (Bucket b = buckets[slot]; b != null; b = b.next) { Object old = b.get(); if (old != null && comparator.rupare(o, old) == 0) return old; } put(hash, o); return o; }
}
</source>