📄 md5.java
字号:
/**
*
* This class computes MD5 hashes.
* Manually translated by Jon Howell <jonh@cs.dartmouth.edu>
* from some public domain C code (md5.c) included with the ssh-1.2.22 source.
* Tue Jan 19 15:55:50 EST 1999
*
* To compute the message digest of a chunk of bytes, create an
* MD5 object 'md5', call md5.update() as needed on buffers full
* of bytes, and then call md5.md5final(), which
* will fill a supplied 16-byte array with the digest.
*
* A main() method is included that hashes the data on System.in.
*
* The hashPassword function was added by Peter Harrison to provide
* a simple means to hash a String, such as a password for use in systems
* that require hashed passwords to be stored.
*
*/
public class MD5 {
int buf[];
long bits;
byte in[];
int inint[];
public String hashPassword( String inString ) {
byte myBuf[] = inString.getBytes();
byte out[] = new byte[16];
update( myBuf );
md5final( out );
return dumpBytes(out);
}
public MD5() {
initMD5();
}
void initMD5() {
buf = new int[4];
// fill the hash accumulator with a seed value
buf[0] = 0x67452301;
buf[1] = 0xefcdab89;
buf[2] = 0x98badcfe;
buf[3] = 0x10325476;
// initially, we've hashed zero bits
bits = 0L;
in = new byte[64];
inint = new int[16];
}
public void update(byte[] newbuf) {
initMD5();
update(newbuf, 0, newbuf.length);
}
public void update(byte[] newbuf, int length) {
update(newbuf, 0, length);
}
public void update(byte[] newbuf, int bufstart, int buflen) {
int t;
int len = buflen;
// shash old bits value for the "Bytes already in" computation
// just below.
t = (int) bits; // (int) cast should just drop high bits, I hope
/* update bitcount */
/* the C code used two 32-bit ints separately, and carefully
* ensured that the carry carried.
* Java has a 64-bit long, which is just what the code really wants.
*/
bits += (long)(len<<3);
t = (t >>> 3) & 0x3f; /* Bytes already in this->in */
/* Handle any leading odd-sized chunks */
/* (that is, any left-over chunk left by last update() */
if (t!=0) {
int p = t;
t = 64 - t;
if (len < t) {
System.arraycopy(newbuf, bufstart, in, p, len);
return;
}
System.arraycopy(newbuf, bufstart, in, p, t);
transform();
bufstart += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64) {
System.arraycopy(newbuf, bufstart, in, 0, 64);
transform();
bufstart += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
/* that is, stash them for the next update(). */
System.arraycopy(newbuf, bufstart, in, 0, len);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
public void md5final(byte[] digest) {
/* "final" is a poor method name in Java. :v) */
int count;
int p; // in original code, this is a pointer; in this java code
// it's an index into the array this->in.
/* Compute number of bytes mod 64 */
count = (int) ((bits >>> 3) & 0x3F);
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = count;
in[p++] = (byte) 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
zeroByteArray(in, p, count);
transform();
/* Now fill the next block with 56 bytes */
zeroByteArray(in, 0, 56);
} else {
/* Pad block to 56 bytes */
zeroByteArray(in, p, count - 8);
}
/* Append length in bits and transform */
// Could use a PUT_64BIT... func here. This is a fairly
// direct translation from the C code, where bits was an array
// of two 32-bit ints.
int lowbits = (int) bits;
int highbits = (int) (bits >>> 32);
PUT_32BIT_LSB_FIRST(in, 56, lowbits);
PUT_32BIT_LSB_FIRST(in, 60, highbits);
transform();
PUT_32BIT_LSB_FIRST(digest, 0, buf[0]);
PUT_32BIT_LSB_FIRST(digest, 4, buf[1]);
PUT_32BIT_LSB_FIRST(digest, 8, buf[2]);
PUT_32BIT_LSB_FIRST(digest, 12, buf[3]);
/* zero sensitive data */
/* notice this misses any sneaking out on the stack. The C
* version uses registers in some spots, perhaps because
* they care about this.
*/
zeroByteArray(in);
zeroIntArray(buf);
bits = 0;
zeroIntArray(inint);
}
/////////////////////////////////////////////////////////////////////
// Below here ye will only finde private functions //
/////////////////////////////////////////////////////////////////////
// There must be a way to do these functions that's
// built into Java, and I just haven't noticed it yet.
private void zeroByteArray(byte[] a) {
zeroByteArray(a, 0, a.length);
}
private void zeroByteArray(byte[] a, int start, int length) {
setByteArray(a, (byte) 0, start, length);
}
private void setByteArray(byte[] a, byte val, int start, int length) {
int i;
int end = start+length;
for (i=start; i<end; i++) {
a[i] = val;
}
}
private void zeroIntArray(int[] a) {
zeroIntArray(a, 0, a.length);
}
private void zeroIntArray(int[] a, int start, int length) {
setIntArray(a, (int) 0, start, length);
}
private void setIntArray(int[] a, int val, int start, int length) {
int i;
int end = start+length;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -