Fast implementation of RSA's MD5 hash generator in Java JDK Beta-2 or higher : MD5 « Security « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Class
8. Collections Data Structure
9. Data Type
10. Database SQL JDBC
11. Design Pattern
12. Development Class
13. EJB3
14. Email
15. Event
16. File Input Output
17. Game
18. Generics
19. GWT
20. Hibernate
21. I18N
22. J2EE
23. J2ME
24. JDK 6
25. JNDI LDAP
26. JPA
27. JSP
28. JSTL
29. Language Basics
30. Network Protocol
31. PDF RTF
32. Reflection
33. Regular Expressions
34. Scripting
35. Security
36. Servlets
37. Spring
38. Swing Components
39. Swing JFC
40. SWT JFace Eclipse
41. Threads
42. Tiny Application
43. Velocity
44. Web Services SOA
45. XML
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java » Security » MD5Screenshots 
Fast implementation of RSA's MD5 hash generator in Java JDK Beta-2 or higher
 



/**
 * Fast implementation of RSA's MD5 hash generator in Java JDK Beta-2 or higher.
 * <p>
 * Originally written by Santeri Paavolainen, Helsinki Finland 1996.<br>
 * (c) Santeri Paavolainen, Helsinki Finland 1996<br>
 * Many changes Copyright (c) 2002 Timothy W Macinta<br>
 * <p>
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <p>
 * 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
 * Library General Public License for more details.
 * <p>
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * <p>
 * See http://www.twmacinta.com/myjava/fast_md5.php for more information
 * on this file and the related files.
 * <p>
 * This was originally a rather straight re-implementation of the
 * reference implementation given in RFC1321 by RSA.  It passes the MD5
 * test suite as defined in RFC1321.
 * <p>
 * Many optimizations made by Timothy W Macinta.  Reduced time to checksum a
 * test file in Java alone to roughly half the time taken compared with
 * java.security.MessageDigest (within an intepretter).  Also added an
 * optional native method to reduce the time even further.
 * See http://www.twmacinta.com/myjava/fast_md5.php for further information
 * on the time improvements achieved.
 * <p>
 * Some bug fixes also made by Timothy W Macinta.
 * <p>
 * Please note: I (Timothy Macinta) have put this code in the
 * com.twmacinta.util package only because it came without a package.  I
 * was not the the original author of the code, although I did
 * optimize it (substantially) and fix some bugs.
 * <p>
 * This Java class has been derived from the RSA Data Security, Inc. MD5 
 * Message-Digest Algorithm and its reference implementation.
 * <p>
 * This class will attempt to use a native method to quickly compute
 * checksums when the appropriate native library is available.  On Linux,
 * this library should be named "MD5.so" and on Windows it should be
 * named "MD5.dll".  The code will attempt to locate the library in the
 * following locations in the order given:
 *
 * <ol>
 *   <li>The path specified by the system property
 *       "com.twmacinta.util.MD5.NATIVE_LIB_FILE"
 *        (be sure to include "MD5.so" or "MD5.dll"
 *        as appropriate at the end of the path).
 *   <li>A platform specific directory beneath the "lib/arch/" directory.
 *       On Linux for x86, this is "lib/arch/linux_x86/".  On Windows for
 *       x86, this is "lib/arch/win32_x86/".
 *   <li>Within the "lib/" directory.
 *   <li>Within the current directory.
 * </ol>
 *
 * <p>
 * If the library is not found, the code will fall back to the default
 * (slower) Java code.
 * <p>
 * As a side effect of having the code search for the native library,
 * SecurityExceptions might be thrown on JVMs that have a restrictive
 * SecurityManager.  The initialization code attempts to silently discard
 * these exceptions and continue, but many SecurityManagers will
 * attempt to notify the user directly of all SecurityExceptions thrown.
 * Consequently, the code has provisions for skipping the search for
 * the native library.  Any of these provisions may be used to skip the
 * search as long as they are performed <i>before</i> the first
 * instance of a com.twmacinta.util.MD5 object is constructed (note that
 * the convenience stream objects will implicitly create an MD5 object).
 * <p>
 * The first option is to set the system property
 * "com.twmacinta.util.MD5.NO_NATIVE_LIB" to "true" or "1".
 * Unfortunately, SecurityManagers may also choose to disallow system
 * property setting, so this won't be of use in all cases.
 * <p>
 * The second option is to call
 * com.twmacinta.util.MD5.initNativeLibrary(false) before any MD5 objects
 * are constructed.
 *
 @author  Santeri Paavolainen <sjpaavol@cc.helsinki.fi>
 @author  Timothy W Macinta (twm@alum.mit.edu) (optimizations and bug fixes)
 */

public class MD5 {
  /**
   * MD5 state
   */
  MD5State  state;
 
  /**
   * If Final() has been called, finals is set to the current finals
   * state. Any Update() causes this to be set to null.
   */
  MD5State  finals;

  /** 
   * Padding for Final()
   */
  static byte padding[] {
    (byte0x800000000000000000000
    00000000000000000000000
    000000000000000000000
  };

  private static boolean native_lib_loaded = false;
  private static boolean native_lib_init_pending = true;
  
  /**
   * Initialize MD5 internal state (object can be reused just by
   * calling Init() after every Final()
   */
  public synchronized void Init () {
    state = new MD5State();
    finals = null;
  }

  /**
   * Class constructor
   */
  public MD5 () {
    if (native_lib_init_pending_initNativeLibrary();
    this.Init();
  }

  /**
   * Initialize class, and update hash with ob.toString()
   *
   @param ob  Object, ob.toString() is used to update hash
   *      after initialization
   */
  public MD5 (Object ob) {
    this();
    Update(ob.toString());
  }

  private void Decode (byte buffer[]int shift, int[] out) {
    /*len += shift;
    for (int i = 0; shift < len; i++, shift += 4) {
      out[i] = ((int) (buffer[shift] & 0xff)) |
  (((int) (buffer[shift + 1] & 0xff)) << 8) |
  (((int) (buffer[shift + 2] & 0xff)) << 16) |
  (((int)  buffer[shift + 3]) << 24);
    }*/

    // unrolled loop (original loop shown above)

    out[0((int) (buffer[shift0xff)) |
      (((int) (buffer[shift + 10xff)) << 8|
      (((int) (buffer[shift + 20xff)) << 16|
      (((int)  buffer[shift + 3]) << 24);
    out[1((int) (buffer[shift + 40xff)) |
      (((int) (buffer[shift + 50xff)) << 8|
      (((int) (buffer[shift + 60xff)) << 16|
      (((int)  buffer[shift + 7]) << 24);
    out[2((int) (buffer[shift + 80xff)) |
      (((int) (buffer[shift + 90xff)) << 8|
      (((int) (buffer[shift + 100xff)) << 16|
      (((int)  buffer[shift + 11]) << 24);
    out[3((int) (buffer[shift + 120xff)) |
      (((int) (buffer[shift + 130xff)) << 8|
      (((int) (buffer[shift + 140xff)) << 16|
      (((int)  buffer[shift + 15]) << 24);
    out[4((int) (buffer[shift + 160xff)) |
      (((int) (buffer[shift + 170xff)) << 8|
      (((int) (buffer[shift + 180xff)) << 16|
      (((int)  buffer[shift + 19]) << 24);
    out[5((int) (buffer[shift + 200xff)) |
      (((int) (buffer[shift + 210xff)) << 8|
      (((int) (buffer[shift + 220xff)) << 16|
      (((int)  buffer[shift + 23]) << 24);
    out[6((int) (buffer[shift + 240xff)) |
      (((int) (buffer[shift + 250xff)) << 8|
      (((int) (buffer[shift + 260xff)) << 16|
      (((int)  buffer[shift + 27]) << 24);
    out[7((int) (buffer[shift + 280xff)) |
      (((int) (buffer[shift + 290xff)) << 8|
      (((int) (buffer[shift + 300xff)) << 16|
      (((int)  buffer[shift + 31]) << 24);
    out[8((int) (buffer[shift + 320xff)) |
      (((int) (buffer[shift + 330xff)) << 8|
      (((int) (buffer[shift + 340xff)) << 16|
      (((int)  buffer[shift + 35]) << 24);
    out[9((int) (buffer[shift + 360xff)) |
      (((int) (buffer[shift + 370xff)) << 8|
      (((int) (buffer[shift + 380xff)) << 16|
      (((int)  buffer[shift + 39]) << 24);
    out[10((int) (buffer[shift + 400xff)) |
      (((int) (buffer[shift + 410xff)) << 8|
      (((int) (buffer[shift + 420xff)) << 16|
      (((int)  buffer[shift + 43]) << 24);
    out[11((int) (buffer[shift + 440xff)) |
      (((int) (buffer[shift + 450xff)) << 8|
      (((int) (buffer[shift + 460xff)) << 16|
      (((int)  buffer[shift + 47]) << 24);
    out[12((int) (buffer[shift + 480xff)) |
      (((int) (buffer[shift + 490xff)) << 8|
      (((int) (buffer[shift + 500xff)) << 16|
      (((int)  buffer[shift + 51]) << 24);
    out[13((int) (buffer[shift + 520xff)) |
      (((int) (buffer[shift + 530xff)) << 8|
      (((int) (buffer[shift + 540xff)) << 16|
      (((int)  buffer[shift + 55]) << 24);
    out[14((int) (buffer[shift + 560xff)) |
      (((int) (buffer[shift + 570xff)) << 8|
      (((int) (buffer[shift + 580xff)) << 16|
      (((int)  buffer[shift + 59]) << 24);
    out[15((int) (buffer[shift + 600xff)) |
      (((int) (buffer[shift + 610xff)) << 8|
      (((int) (buffer[shift + 620xff)) << 16|
      (((int)  buffer[shift + 63]) << 24);
  }

  private native void Transform_native (int[] state, byte buffer[]int shift, int length);

  private void Transform (MD5State state, byte buffer[]int shift, int[] decode_buf) {
    int 
      a = state.state[0],
      b = state.state[1],
      c = state.state[2],
      d = state.state[3],
      x[] = decode_buf;

    Decode(buffer, shift, decode_buf);
    
    /* Round 1 */
    a += ((b & c(~b & d)) + x00xd76aa478/* 1 */
    a = ((a << 7(a >>> 25)) + b;
    d += ((a & b(~a & c)) + x10xe8c7b756/* 2 */
    d = ((d << 12(d >>> 20)) + a;
    c += ((d & a(~d & b)) + x20x242070db/* 3 */
    c = ((c << 17(c >>> 15)) + d;
    b += ((c & d(~c & a)) + x30xc1bdceee/* 4 */
    b = ((b << 22(b >>> 10)) + c;

    a += ((b & c(~b & d)) + x40xf57c0faf/* 5 */
    a = ((a << 7(a >>> 25)) + b;
    d += ((a & b(~a & c)) + x50x4787c62a/* 6 */
    d = ((d << 12(d >>> 20)) + a;
    c += ((d & a(~d & b)) + x60xa8304613/* 7 */
    c = ((c << 17(c >>> 15)) + d;
    b += ((c & d(~c & a)) + x70xfd469501/* 8 */
    b = ((b << 22(b >>> 10)) + c;

    a += ((b & c(~b & d)) + x80x698098d8/* 9 */
    a = ((a << 7(a >>> 25)) + b;
    d += ((a & b(~a & c)) + x90x8b44f7af/* 10 */
    d = ((d << 12(d >>> 20)) + a;
    c += ((d & a(~d & b)) + x[100xffff5bb1/* 11 */
    c = ((c << 17(c >>> 15)) + d;
    b += ((c & d(~c & a)) + x[110x895cd7be/* 12 */
    b = ((b << 22(b >>> 10)) + c;

    a += ((b & c(~b & d)) + x[120x6b901122/* 13 */
    a = ((a << 7(a >>> 25)) + b;
    d += ((a & b(~a & c)) + x[130xfd987193/* 14 */
    d = ((d << 12(d >>> 20)) + a;
    c += ((d & a(~d & b)) + x[140xa679438e/* 15 */
    c = ((c << 17(c >>> 15)) + d;
    b += ((c & d(~c & a)) + x[150x49b40821/* 16 */
    b = ((b << 22(b >>> 10)) + c;
    
    
    /* Round 2 */
    a += ((b & d(c & ~d)) + x10xf61e2562/* 17 */
    a = ((a << 5(a >>> 27)) + b;
    d += ((a & c(b & ~c)) + x60xc040b340/* 18 */
    d = ((d << 9(d >>> 23)) + a;
    c += ((d & b(a & ~b)) + x[110x265e5a51/* 19 */
    c = ((c << 14(c >>> 18)) + d;
    b += ((c & a(d & ~a)) + x00xe9b6c7aa/* 20 */
    b = ((b << 20(b >>> 12)) + c;

    a += ((b & d(c & ~d)) + x50xd62f105d/* 21 */
    a = ((a << 5(a >>> 27)) + b;
    d += ((a & c(b & ~c)) + x[100x02441453/* 22 */
    d = ((d << 9(d >>> 23)) + a;
    c += ((d & b(a & ~b)) + x[150xd8a1e681/* 23 */
    c = ((c << 14(c >>> 18)) + d;
    b += ((c & a(d & ~a)) + x40xe7d3fbc8/* 24 */
    b = ((b << 20(b >>> 12)) + c;

    a += ((b & d(c & ~d)) + x90x21e1cde6/* 25 */
    a = ((a << 5(a >>> 27)) + b;
    d += ((a & c(b & ~c)) + x[140xc33707d6/* 26 */
    d = ((d << 9(d >>> 23)) + a;
    c += ((d & b(a & ~b)) + x30xf4d50d87/* 27 */
    c = ((c << 14(c >>> 18)) + d;
    b += ((c & a(d & ~a)) + x80x445a14ed/* 28 */
    b = ((b << 20(b >>> 12)) + c;

    a += ((b & d(c & ~d)) + x[130xa9e3e905/* 29 */
    a = ((a << 5(a >>> 27)) + b;
    d += ((a & c(b & ~c)) + x20xfcefa3f8/* 30 */
    d = ((d << 9(d >>> 23)) + a;
    c += ((d & b(a & ~b)) + x70x676f02d9/* 31 */
    c = ((c << 14(c >>> 18)) + d;
    b += ((c & a(d & ~a)) + x[120x8d2a4c8a/* 32 */
    b = ((b << 20(b >>> 12)) + c;
    
    
    /* Round 3 */
    a += (b ^ c ^ d+ x50xfffa3942;      /* 33 */
    a = ((a << 4(a >>> 28)) + b;
    d += (a ^ b ^ c+ x80x8771f681;      /* 34 */
    d = ((d << 11(d >>> 21)) + a;
    c += (d ^ a ^ b+ x[110x6d9d6122;      /* 35 */
    c = ((c << 16(c >>> 16)) + d;
    b += (c ^ d ^ a+ x[140xfde5380c;      /* 36 */
    b = ((b << 23(b >>> 9)) + c;
    
    a += (b ^ c ^ d+ x10xa4beea44;      /* 37 */
    a = ((a << 4(a >>> 28)) + b;
    d += (a ^ b ^ c+ x40x4bdecfa9;      /* 38 */
    d = ((d << 11(d >>> 21)) + a;
    c += (d ^ a ^ b+ x70xf6bb4b60;      /* 39 */
    c = ((c << 16(c >>> 16)) + d;
    b += (c ^ d ^ a+ x[100xbebfbc70;      /* 40 */
    b = ((b << 23(b >>> 9)) + c;
    
    a += (b ^ c ^ d+ x[130x289b7ec6;      /* 41 */
    a = ((a << 4(a >>> 28)) + b;
    d += (a ^ b ^ c+ x00xeaa127fa;      /* 42 */
    d = ((d << 11(d >>> 21)) + a;
    c += (d ^ a ^ b+ x30xd4ef3085;      /* 43 */
    c = ((c << 16(c >>> 16)) + d;
    b += (c ^ d ^ a+ x60x04881d05;      /* 44 */
    b = ((b << 23(b >>> 9)) + c;
    
    a += (b ^ c ^ d+ x90xd9d4d039;      /* 33 */
    a = ((a << 4(a >>> 28)) + b;
    d += (a ^ b ^ c+ x[120xe6db99e5;      /* 34 */
    d = ((d << 11(d >>> 21)) + a;
    c += (d ^ a ^ b+ x[150x1fa27cf8;      /* 35 */
    c = ((c << 16(c >>> 16)) + d;
    b += (c ^ d ^ a+ x20xc4ac5665;      /* 36 */
    b = ((b << 23(b >>> 9)) + c;
    

    /* Round 4 */
    a += (c ^ (b | ~d)) + x00xf4292244/* 49 */
    a = ((a << 6(a >>> 26)) + b;
    d += (b ^ (a | ~c)) + x70x432aff97/* 50 */
    d = ((d << 10(d >>> 22)) + a;
    c += (a ^ (d | ~b)) + x[140xab9423a7/* 51 */
    c = ((c << 15(c >>> 17)) + d;
    b += (d ^ (c | ~a)) + x50xfc93a039/* 52 */
    b = ((b << 21(b >>> 11)) + c;

    a += (c ^ (b | ~d)) + x[120x655b59c3/* 53 */
    a = ((a << 6(a >>> 26)) + b;
    d += (b ^ (a | ~c)) + x30x8f0ccc92/* 54 */
    d = ((d << 10(d >>> 22)) + a;
    c += (a ^ (d | ~b)) + x[100xffeff47d/* 55 */
    c = ((c << 15(c >>> 17)) + d;
    b += (d ^ (c | ~a)) + x10x85845dd1/* 56 */
    b = ((b << 21(b >>> 11)) + c;

    a += (c ^ (b | ~d)) + x80x6fa87e4f/* 57 */
    a = ((a << 6(a >>> 26)) + b;
    d += (b ^ (a | ~c)) + x[150xfe2ce6e0/* 58 */
    d = ((d << 10(d >>> 22)) + a;
    c += (a ^ (d | ~b)) + x60xa3014314/* 59 */
    c = ((c << 15(c >>> 17)) + d;
    b += (d ^ (c | ~a)) + x[130x4e0811a1/* 60 */
    b = ((b << 21(b >>> 11)) + c;

    a += (c ^ (b | ~d)) + x40xf7537e82/* 61 */
    a = ((a << 6(a >>> 26)) + b;
    d += (b ^ (a | ~c)) + x[110xbd3af235/* 62 */
    d = ((d << 10(d >>> 22)) + a;
    c += (a ^ (d | ~b)) + x20x2ad7d2bb/* 63 */
    c = ((c << 15(c >>> 17)) + d;
    b += (d ^ (c | ~a)) + x90xeb86d391/* 64 */
    b = ((b << 21(b >>> 11)) + c;

    state.state[0+= a;
    state.state[1+= b;
    state.state[2+= c;
    state.state[3+= d;
  }

  /** 
   * Updates hash with the bytebuffer given (using at maximum length bytes from
   * that buffer)
   *
   @param state Which state is updated
   @param buffer  Array of bytes to be hashed
   @param offset  Offset to buffer array
   @param length  Use at maximum `length' bytes (absolute
   *      maximum is buffer.length)
   */
  public void Update (MD5State stat, byte buffer[]int offset, int length) {
    int index, partlen, i, start;
    finals = null;

    /* Length can be told to be shorter, but not inter */
    if ((length - offset)> buffer.length)
      length = buffer.length - offset;

    /* compute number of bytes mod 64 */

    index = (int) (stat.count & 0x3f);
    stat.count += length;
    
    partlen = 64 - index;

    if (length >= partlen) {
      if (native_lib_loaded) {
  
  // update state (using native method) to reflect input

  if (partlen == 64) {
    partlen = 0;
  else {
    for (i = 0; i < partlen; i++)
      stat.buffer[i + index= buffer[i + offset];
    Transform_native(stat.state, stat.buffer, 064);
  }
  Transform_native(stat.state, buffer, partlen + offset, length - partlen);
  i = partlen + ((length - partlen6464;
      else {
  
  // update state (using only Java) to reflect input

  int[] decode_buf = new int[16];
  if (partlen == 64) {
    partlen = 0;
  else {
    for (i = 0; i < partlen; i++)
      stat.buffer[i + index= buffer[i + offset];
    Transform(stat, stat.buffer, 0, decode_buf);
  }
  for (i = partlen; (i + 63< length; i+= 64) {
    Transform(stat, buffer, i + offset, decode_buf);
  }
      }
      index = 0;
    else 
      i = 0;

    /* buffer remaining input */
    if (i < length) {
      start = i;
      for (; i < length; i++) {
  stat.buffer[index + i - start= buffer[i + offset];
      }
    }
  }

  /* 
   * Update()s for other datatypes than byte[] also. Update(byte[], int)
   * is only the main driver.
   */

  /**
   * Plain update, updates this object
   */

  public void Update (byte buffer[]int offset, int length) {
      Update(this.state, buffer, offset, length);
  }

  public void Update (byte buffer[]int length) {
      Update(this.state, buffer, 0, length);
  }

  /**
   * Updates hash with given array of bytes
   *
   @param buffer  Array of bytes to use for updating the hash
   */
  public void Update (byte buffer[]) {
      Update(buffer, 0, buffer.length);
  }

  /**
   * Updates hash with a single byte
   *
   @param b   Single byte to update the hash
   */
  public void Update (byte b) {
    byte buffer[] new byte[1];
    buffer[0= b;

    Update(buffer, 1);
  }
  
  /**
   * Update buffer with given string.  Note that because the version of
   * the s.getBytes() method without parameters is used to convert the
   * string to a byte array, the results of this method may be different
   * on different platforms.  The s.getBytes() method converts the string
   * into a byte array using the current platform's default character set
   * and may therefore have different results on platforms with different
   * default character sets.  If a version that works consistently
   * across platforms with different default character sets is desired,
   * use the overloaded version of the Update() method which takes a
   * string and a character encoding.
   *
   @param s   String to be update to hash (is used as
   *            s.getBytes())
   */
  public void Update (String s) {
    byte chars[] = s.getBytes();
    Update(chars, chars.length);
  }

  /**
   * Update buffer with given string using the given encoding.  If the
   * given encoding is null, the encoding "ISO8859_1" is used.
   *
   @param s   String to be update to hash (is used as
   *            s.getBytes(charset_name))
   @param charset_name The character set to use to convert s to a
   *                    byte array, or null if the "ISO8859_1"
   *                    character set is desired.
   @exception         java.io.UnsupportedEncodingException If the named
   *                    charset is not supported.
   */
  public void Update (String s, String charset_namethrows java.io.UnsupportedEncodingException {
    if (charset_name == nullcharset_name = "ISO8859_1";
    byte chars[] = s.getBytes(charset_name);
    Update(chars, chars.length);
  }

  /**
   * Update buffer with a single integer (only & 0xff part is used,
   * as a byte)
   *
   @param i   Integer value, which is then converted to 
   *      byte as i & 0xff
   */

  public void Update (int i) {
      Update((byte) (i & 0xff));
  }

  private byte[] Encode (int input[]int len) {
    int   i, j;
    byte  out[];

    out = new byte[len];

    for (i = j = 0; j  < len; i++, j += 4) {
      out[j(byte) (input[i0xff);
      out[j + 1(byte) ((input[i>>> 80xff);
      out[j + 2(byte) ((input[i>>> 160xff);
      out[j + 3(byte) ((input[i>>> 240xff);
    }

    return out;
  }

  /**
   * Returns array of bytes (16 bytes) representing hash as of the
   * current state of this object. Note: getting a hash does not
   * invalidate the hash object, it only creates a copy of the real
   * state which is finalized. 
   *
   @return  Array of 16 bytes, the hash of all updated bytes
   */
  public synchronized byte[] Final () {
    byte  bits[];
    int   index, padlen;
    MD5State  fin;

    if (finals == null) {
      fin = new MD5State(state);

      int[] count_ints = {(int) (fin.count << 3)(int) (fin.count >> 29)};
      bits = Encode(count_ints, 8);
    
      index = (int) (fin.count & 0x3f);
      padlen = (index < 56(56 - index(120 - index);

      Update(fin, padding, 0, padlen);
      Update(fin, bits, 08);  

      /* Update() sets finals to null */
      finals = fin;
    

    return Encode(finals.state, 16);
  }    

  /**
   * Turns array of bytes into string representing each byte as
   * unsigned hex number.
   
   @param hash  Array of bytes to convert to hex-string
   @return  Generated hex string
   */
  public static String asHex (byte hash[]) {
    StringBuffer buf = new StringBuffer(hash.length * 2);
    int i;

    for (i = 0; i < hash.length; i++) {
      if (((inthash[i0xff0x10
  buf.append("0");

      buf.append(Long.toString((inthash[i0xff16));
    }

    return buf.toString();
  }

  /**
   * Returns 32-character hex representation of this objects hash
   *
   @return String of this object's hash
   */
  public String asHex () {
    return asHex(this.Final());
  }

  public static synchronized final void initNativeLibrary(boolean disallow_lib_loading) {
    if (disallow_lib_loading) {
      native_lib_init_pending = false;
    else {
      _initNativeLibrary();
    }
  }

  private static synchronized final void  _initNativeLibrary() {
    if (!native_lib_init_pendingreturn;
    native_lib_loaded = _loadNativeLibrary();
    native_lib_init_pending = false;
  }

  private static synchronized final boolean _loadNativeLibrary() {
    return false;
  }

}


/**
 * Fast implementation of RSA's MD5 hash generator in Java JDK Beta-2 or higher<br>
 * Originally written by Santeri Paavolainen, Helsinki Finland 1996 <br>
 * (c) Santeri Paavolainen, Helsinki Finland 1996 <br>
 * Some changes Copyright (c) 2002 Timothy W Macinta <br>
 * <p>
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <p>
 * 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
 * Library General Public License for more details.
 * <p>
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * <p>
 * See http://www.twmacinta.com/myjava/fast_md5.php for more information
 * on this file.
 * <p>
 * Contains internal state of the MD5 class
 * <p>
 * Please note: I (Timothy Macinta) have put this code in the
 * com.twmacinta.util package only because it came without a package.  I
 * was not the the original author of the code, although I did
 * optimize it (substantially) and fix some bugs.
 *
 @author  Santeri Paavolainen <sjpaavol@cc.helsinki.fi>
 @author  Timothy W Macinta (twm@alum.mit.edu) (optimizations and bug fixes)
 **/

class MD5State {
  /**
   * 128-bit state 
   */
  int state[];
  
  /**
   * 64-bit character count
   */
  long count;
  
  /**
   * 64-byte buffer (512 bits) for storing to-be-hashed characters
   */
  byte  buffer[];

  public MD5State() {
    buffer = new byte[64];
    count = 0;
    state = new int[4];
    
    state[00x67452301;
    state[10xefcdab89;
    state[20x98badcfe;
    state[30x10325476;

  }

  /** Create this State as a copy of another state */
  public MD5State (MD5State from) {
    this();
    
    int i;
    
    for (i = 0; i < buffer.length; i++)
      this.buffer[ifrom.buffer[i];
    
    for (i = 0; i < state.length; i++)
      this.state[ifrom.state[i];
    
    this.count = from.count;
  }
};

   
  
Related examples in the same category
1. OTP one-time password calculationOTP one-time password calculation
2. Applet to serve as an s/key calculator application wrapper around otp class
3. Creating a Keyed Digest Using MD5
4. MD5 BASE64 checksum for the specified input string.
5. MD5 InputStream
6. Implements MD5 functionality on a stream.
7. MD5 algorithm RFC 1321
8. Contains internal state of the MD5 class
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.