/** * 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. */ 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]; } } }