001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 The ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| You may obtain a copy of the License at                                  |
008|                                                                          |
009|    http://www.apache.org/licenses/LICENSE-2.0                            |
010|                                                                          |
011| Unless required by applicable law or agreed to in writing, software      |
012| distributed under the License is distributed on an "AS IS" BASIS,        |
013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
014| See the License for the specific language governing permissions and      |
015| limitations under the License.                                           |
016+-------------------------------------------------------------------------*/
017package org.conqat.lib.commons.digest;
018
019import java.security.MessageDigest;
020
021import org.conqat.lib.commons.assertion.CCSMAssert;
022import org.conqat.lib.commons.collections.ByteArrayWrapper;
023
024/**
025 * An MD5 digest. This is just a thin wrapper around a byte array with some
026 * convenience methods. This class is used instead of plain strings to save both
027 * memory and (some) execution time.
028 */
029public final class MD5Digest extends ByteArrayWrapper {
030
031        /** Version used for serialization. */
032        private static final long serialVersionUID = 1;
033
034        /** Number of bytes in an MD5 sum. */
035        public static final int MD5_BYTES = 16;
036
037        /**
038         * Constructor. This calls {@link MessageDigest#digest()}, so the digest
039         * will be reset afterwards.
040         */
041        public MD5Digest(MessageDigest digest) {
042                this(digest.digest());
043        }
044
045        /** Constructor. */
046        public MD5Digest(byte[] digest) {
047                super(digest);
048                CCSMAssert.isTrue(digest.length == MD5_BYTES, "Invalid size of MD5 digest!");
049        }
050
051        /**
052         * Inserts the digest data into the given MD. This method is used to rehash
053         * multiple hashes.
054         * <p>
055         * This method is provided instead of a getter, to keep this immutable.
056         */
057        public void insertIntoDigest(MessageDigest digest) {
058                digest.update(array);
059        }
060
061        /**
062         * Calculates and returns a hashcode that only depends on the first 3 bytes.
063         */
064        public int partialHashCode() {
065                return array[0] | (array[1] << 8) | (array[2] << 16);
066        }
067}