您的当前位置:首页正文

db2使用Java存储过程实现MD5函数

2023-11-09 来源:帮我找美食网
java.security.MessageDigest;import COM.ibm.db2.app.UDF;public class MD5UDF extends UDF { public static String MD5(String s) { String s1 = new String(""); char hexDigits[] = { ‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘ }; try { byte[] strTemp = s.getBytes(); MessageDigest mdTemp = MessageDigest.getInstance("MD5"); mdTemp.update(strTemp); byte[] md = mdTemp.digest(); int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } s1 = new String(str); } catch (Exception e) { System.out.println(e.getMessage()); } return "{" + s1 + "}"; } public static void main(String[] args){ System.out.println(MD5("asdf")); }}

3.运行javac编译

javac MD5UDF.java

4.运行jar打包MD5UDF.class 为 MD5UDF.jar

jar cf MD5UDF.jar MD5UDF.class

5.连上数据库,运行安装.jar文件到数据库(C:Documents and SettingsALL USERSApplication DataIBMDB2DB2COPY1functionjarEN 目录下)

db2 connect to sample

db2 "CALL sqlj.install_jar(‘file:E:MD5UDF.jar‘, ‘MD5UDF‘)"

6.登录数据库创建function

DROP FUNCTION BI_MD5;CREATE FUNCTION BI_MD5(VARCHAR(200))RETURNS VARCHAR(70)EXTERNAL NAME ‘MD5UDF:MD5UDF.MD5‘FENCED VARIANTNO SQLEXTERNAL ACTION LANGUAGE JAVAPARAMETER STYLE JAVA

7.调用测试

select bi_MD5(‘12345‘) from sysibm.dual

OK!

 

结论:

1.安装、删除、替换jar文件

db2 "CALL sqlj.install_jar(‘file:D:someBookesJavaMD5UDF2.jar‘, ‘BIMD5‘)"

db2 "CALL sqlj.remove_jar(‘BIMD5‘)"

db2 "CALL sqlj.replace_jar(‘file:E:mydb2mylog.jar‘, ‘BIMD5‘)"

2.刷新已经调用的jar或class,不用重启实例就生效:

db2 "CALL SQLJ.REFRESH_CLASSES()"

3.调用的Java方式必须是静态的。

4.编译成jar包的SDK版本必须和db2的版本相符

否则会报错

技术分享

 

 参考文章:技术分享http://bbs.chinaunix.net/thread-966098-1-1.html技术分享http://www.ibm.com/developerworks/cn/data/library/techarticle/dm-1012liucs/技术分享http://www.ibm.com/developerworks/data/library/techarticle/dm-0510law/index.html

db2使用Java存储过程实现MD5函数

标签:

小编还为您整理了以下内容,可能对您也有帮助:

可变MD5加密(Java实现)

可变在这里含义很简单 就是最终的加密结果是可变的 而非必需按标准MD 加密实现 Java类库security中的MessageDigest类就提供了MD 加密的支持 实现起来非常方便 为了实现更多效果 我们可以如下设计MD 工具类

Java代码

package ** ** util;

import java security MessageDigest;

/**

* 标准MD 加密方法 使用java类库的security包的MessageDigest类处理

* @author Sarin

*/

public class MD {

/**

* 获得MD 加密密码的方法

*/

public static String getMD ofStr(String origString) {

String origMD = null;

try {

MessageDigest md = MessageDigest getInstance( MD );

byte[] result = md digest(origString getBytes());

origMD = byteArray HexStr(result);

} catch (Exception e) {

e printStackTrace();

}

return origMD ;

}

/**

* 处理字节数组得到MD 密码的方法

*/

private static String byteArray HexStr(byte[] bs) {

StringBuffer *** = new StringBuffer();

for (byte b : bs) {

*** append(byte HexStr(b));

}

return *** toString();

}

/**

* 字节标准移位转十六进制方法

*/

private static String byte HexStr(byte b) {

String hexStr = null;

int n = b;

if (n < ) {

//若需要自定义加密 请修改这个移位算法即可

n = b & x F + ;

}

hexStr = Integer toHexString(n / ) + Integer toHexString(n % );

return hexStr toUpperCase();

}

/**

* 提供一个MD 多次加密方法

*/

public static String getMD ofStr(String origString int times) {

String md = getMD ofStr(origString);

for (int i = ; i < times ; i++) {

md = getMD ofStr(md );

}

return getMD ofStr(md );

}

/**

* 密码验证方法

*/

public static boolean verifyPassword(String inputStr String MD Code) {

return getMD ofStr(inputStr) equals(MD Code);

}

/**

* 重载一个多次加密时的密码验证方法

*/

public static boolean verifyPassword(String inputStr String MD Code int times) {

return getMD ofStr(inputStr times) equals(MD Code);

}

/**

* 提供一个测试的主函数

*/

public static void main(String[] args) {

System out println( : + getMD ofStr( ));

System out println( : + getMD ofStr( ));

System out println( sarin: + getMD ofStr( sarin ));

System out println( : + getMD ofStr( ));

}

}

可以看出实现的过程非常简单 因为由java类库提供了处理支持 但是要清楚的是这种方式产生的密码不是标准的MD 码 它需要进行移位处理才能得到标准MD 码 这个程序的关键之处也在这了 怎么可变?调整移位算法不就可变了么!不进行移位 也能够得到 位的密码 这就不是标准加密了 只要加密和验证过程使用相同的算法就可以了

MD 加密还是很安全的 像CMD 那些穷举破解的只是针对标准MD 加密的结果进行的 如果自定义移位算法后 它还有效么?可以说是无解的了 所以MD 非常安全可靠

为了更可变 还提供了多次加密的方法 可以在MD 基础之上继续MD 就是对 位的第一次加密结果再MD 恩 这样去破解?没有任何意义

这样在MIS系统中使用 安全可靠 欢迎交流 希望对使用者有用

我们最后看看由MD 加密算法实现的类 那是非常庞大的

Java代码

import java lang reflect *;

/**

* **********************************************

* md 类实现了RSA Data Security Inc 在提交给IETF

* 的RFC 中的MD message digest 算法

* ***********************************************

*/

public class MD {

/* 下面这些S S 实际上是一个 * 的矩阵 在原始的C实现中是用#define 实现的

这里把它们实现成为static final是表示了只读 切能在同一个进程空间内的多个

Instance间共享*/

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final byte[] PADDING = {

};

/* 下面的三个成员是MD 计算过程中用到的 个核心数据 在原始的C实现中

被定义到MD _CTX结构中

*/

private long[] state = new long[ ]; // state (ABCD)

private long[] count = new long[ ]; // number of bits molo ^ (l *** first)

private byte[] buffer = new byte[ ]; // input buffer

/* digestHexStr是MD 的唯一一个公共成员 是最新一次计算结果的

进制ASCII表示

*/

public String digestHexStr;

/* digest 是最新一次计算结果的 进制内部表示 表示 bit的MD 值

*/

private byte[] digest = new byte[ ];

/*

getMD ofStr是类MD 最主要的公共方法 入口参数是你想要进行MD 变换的字符串

返回的是变换完的结果 这个结果是从公共成员digestHexStr取得的.

*/

public String getMD ofStr(String inbuf) {

md Init();

md Update(inbuf getBytes() inbuf length());

md Final();

digestHexStr = ;

for (int i = ; i < ; i++) {

digestHexStr += byteHEX(digest[i]);

}

return digestHexStr;

}

// 这是MD 这个类的标准构造函数 JavaBean要求有一个public的并且没有参数的构造函数

public MD () {

md Init();

return;

}

/* md Init是一个初始化函数 初始化核心变量 装入标准的幻数 */

private void md Init() {

count[ ] = L;

count[ ] = L;

///* Load magic initialization constants

state[ ] = x L;

state[ ] = xefcdab L;

state[ ] = x badcfeL;

state[ ] = x L;

return;

}

/* F G H I 是 个基本的MD 函数 在原始的MD 的C实现中 由于它们是

简单的位运算 可能出于效率的考虑把它们实现成了宏 在java中 我们把它们

实现成了private方法 名字保持了原来C中的 */

private long F(long x long y long z) {

return (x & y) | ((~x) & z);

}

private long G(long x long y long z) {

return (x & z) | (y & (~z));

}

private long H(long x long y long z) {

return x ^ y ^ z;

}

private long I(long x long y long z) {

return y ^ (x | (~z));

}

/*

FF GG HH和II将调用F G H I进行近一步变换

FF GG HH and II transformations for rounds and

Rotation is separate from addition to prevent reputation

*/

private long FF(long a long b long c long d long x long s long ac) {

a += F(b c d) + x + ac;

a = ((int) a << s) | ((int) a >>> ( s));

a += b;

return a;

}

private long GG(long a long b long c long d long x long s long ac) {

a += G(b c d) + x + ac;

a = ((int) a << s) | ((int) a >>> ( s));

a += b;

return a;

}

private long HH(long a long b long c long d long x long s long ac) {

a += H(b c d) + x + ac;

a = ((int) a << s) | ((int) a >>> ( s));

a += b;

return a;

}

private long II(long a long b long c long d long x long s long ac) {

a += I(b c d) + x + ac;

a = ((int) a << s) | ((int) a >>> ( s));

a += b;

return a;

}

/*

md Update是MD 的主计算过程 inbuf是要变换的字节串 inputlen是长度 这个

函数由getMD ofStr调用 调用之前需要调用md init 因此把它设计成private的

*/

private void md Update(byte[] inbuf int inputLen) {

int i index partLen;

byte[] block = new byte[ ];

index = (int) (count[ ] >>> ) & x F;

// /* Update number of bits */

if ((count[ ] += (inputLen << )) < (inputLen << ))

count[ ]++;

count[ ] += (inputLen >>> );

partLen = index;

// Transform as many times as possible

if (inputLen >= partLen) {

md Memcpy(buffer inbuf index partLen);

md Transform(buffer);

for (i = partLen; i + < inputLen; i += ) {

md Memcpy(block inbuf i );

md Transform(block);

}

index = ;

} else

i = ;

///* Buffer remaining input */

md Memcpy(buffer inbuf index i inputLen i);

}

/*

md Final整理和填写输出结果

*/

private void md Final() {

byte[] bits = new byte[ ];

int index padLen;

///* Save number of bits */

Encode(bits count );

///* Pad out to mod

index = (int) (count[ ] >>> ) & x f;

padLen = (index < ) ? ( index) : ( index);

md Update(PADDING padLen);

///* Append length (before padding) */

md Update(bits );

///* Store state in digest */

Encode(digest state );

}

/* md Memcpy是一个内部使用的byte数组的块拷贝函数 从input的inpos开始把len长度的

字节拷贝到output的outpos位置开始

*/

private void md Memcpy(byte[] output byte[] input int outpos int inpos int len) {

int i;

for (i = ; i < len; i++)

output[outpos + i] = input[inpos + i];

}

/*

md Transform是MD 核心变换程序 有md Update调用 block是分块的原始字节

*/

private void md Transform(byte block[]) {

long a = state[ ] b = state[ ] c = state[ ] d = state[ ];

long[] x = new long[ ];

Decode(x block );

/* Round */

a = FF(a b c d x[ ] S xd aa L); /* */

d = FF(d a b c x[ ] S xe c b L); /* */

c = FF(c d a b x[ ] S x dbL); /* */

b = FF(b c d a x[ ] S xc bdceeeL); /* */

a = FF(a b c d x[ ] S xf c fafL); /* */

d = FF(d a b c x[ ] S x c aL); /* */

c = FF(c d a b x[ ] S xa L); /* */

b = FF(b c d a x[ ] S xfd L); /* */

a = FF(a b c d x[ ] S x d L); /* */

d = FF(d a b c x[ ] S x b f afL); /* */

c = FF(c d a b x[ ] S xffff bb L); /* */

b = FF(b c d a x[ ] S x cd beL); /* */

a = FF(a b c d x[ ] S x b L); /* */

d = FF(d a b c x[ ] S xfd L); /* */

c = FF(c d a b x[ ] S xa eL); /* */

b = FF(b c d a x[ ] S x b L); /* */

/* Round */

a = GG(a b c d x[ ] S xf e L); /* */

d = GG(d a b c x[ ] S xc b L); /* */

c = GG(c d a b x[ ] S x e a L); /* */

b = GG(b c d a x[ ] S xe b c aaL); /* */

a = GG(a b c d x[ ] S xd f dL); /* */

d = GG(d a b c x[ ] S x L); /* */

c = GG(c d a b x[ ] S xd a e L); /* */

b = GG(b c d a x[ ] S xe d fbc L); /* */

a = GG(a b c d x[ ] S x e cde L); /* */

d = GG(d a b c x[ ] S xc d L); /* */

c = GG(c d a b x[ ] S xf d d L); /* */

b = GG(b c d a x[ ] S x a edL); /* */

a = GG(a b c d x[ ] S xa e e L); /* */

d = GG(d a b c x[ ] S xfcefa f L); /* */

c = GG(c d a b x[ ] S x f d L); /* */

b = GG(b c d a x[ ] S x d a c aL); /* */

/* Round */

a = HH(a b c d x[ ] S xfffa L); /* */

d = HH(d a b c x[ ] S x f L); /* */

c = HH(c d a b x[ ] S x d d L); /* */

b = HH(b c d a x[ ] S xfde cL); /* */

a = HH(a b c d x[ ] S xa beea L); /* */

d = HH(d a b c x[ ] S x bdecfa L); /* */

c = HH(c d a b x[ ] S xf bb b L); /* */

b = HH(b c d a x[ ] S xbebfbc L); /* */

a = HH(a b c d x[ ] S x b ec L); /* */

d = HH(d a b c x[ ] S xeaa faL); /* */

c = HH(c d a b x[ ] S xd ef L); /* */

b = HH(b c d a x[ ] S x d L); /* */

a = HH(a b c d x[ ] S xd d d L); /* */

d = HH(d a b c x[ ] S xe db e L); /* */

c = HH(c d a b x[ ] S x fa cf L); /* */

b = HH(b c d a x[ ] S xc ac L); /* */

/* Round */

a = II(a b c d x[ ] S xf L); /* */

d = II(d a b c x[ ] S x aff L); /* */

c = II(c d a b x[ ] S xab a L); /* */

b = II(b c d a x[ ] S xfc a L); /* */

a = II(a b c d x[ ] S x b c L); /* */

d = II(d a b c x[ ] S x f ccc L); /* */

c = II(c d a b x[ ] S xffeff dL); /* */

b = II(b c d a x[ ] S x dd L); /* */

a = II(a b c d x[ ] S x fa e fL); /* */

d = II(d a b c x[ ] S xfe ce e L); /* */

c = II(c d a b x[ ] S xa L); /* */

b = II(b c d a x[ ] S x e a L); /* */

a = II(a b c d x[ ] S xf e L); /* */

d = II(d a b c x[ ] S xbd af L); /* */

c = II(c d a b x[ ] S x ad d bbL); /* */

b = II(b c d a x[ ] S xeb d L); /* */

state[ ] += a;

state[ ] += b;

state[ ] += c;

state[ ] += d;

}

/*Encode把long数组按顺序拆成byte数组 因为java的long类型是 bit的

只拆低 bit 以适应原始C实现的用途

*/

private void Encode(byte[] output long[] input int len) {

int i j;

for (i = j = ; j < len; i++ j += ) {

output[j] = (byte) (input[i] & xffL);

output[j + ] = (byte) ((input[i] >>> ) & xffL);

output[j + ] = (byte) ((input[i] >>> ) & xffL);

output[j + ] = (byte) ((input[i] >>> ) & xffL);

}

}

/*Decode把byte数组按顺序合成成long数组 因为java的long类型是 bit的

只合成低 bit 高 bit清零 以适应原始C实现的用途

*/

private void Decode(long[] output byte[] input int len) {

int i j;

for (i = j = ; j < len; i++ j += )

output[i] = b iu(input[j]) | (b iu(input[j + ]) << ) | (b iu(input[j + ]) << )

| (b iu(input[j + ]) << );

return;

}

/*

b iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序 因为java没有unsigned运算

*/

public static long b iu(byte b) {

return b < ? b & x F + : b;

}

/*byteHEX() 用来把一个byte类型的数转换成十六进制的ASCII表示

因为java中的byte的toString无法实现这一点 我们又没有C语言中的

sprintf(outbuf % X ib)

*/

public static String byteHEX(byte ib) {

char[] Digit = { A B C D E F };

char[] ob = new char[ ];

ob[ ] = Digit[(ib >>> ) & X F];

ob[ ] = Digit[ib & X F];

String s = new String(ob);

return s;

}

public static void main(String args[]) {

MD m = new MD ();

if (Array getLength(args) == ) { //如果没有参数 执行标准的Test Suite

System out println( MD Test suite: );

System out println( MD ( ): + m getMD ofStr( ));

System out println( MD ( a ): + m getMD ofStr( a ));

System out println( MD ( abc ): + m getMD ofStr( abc ));

System out println( MD ( ): + m getMD ofStr( ));

System out println( MD ( ): + m getMD ofStr( ));

System out println( MD ( message digest ): + m getMD ofStr( message digest ));

System out println( MD ( abcdefghijklmnopqrstuvwxyz ): + m getMD ofStr( abcdefghijklmnopqrstuvwxyz ));

System out println( MD ( ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ):

+ m getMD ofStr( ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ));

} else

System out println( MD ( + args[ ] + )= + m getMD ofStr(args[ ]));

}

lishixin/Article/program/Java/hx/201311/26604

    可变MD5加密(Java实现)

    可变在这里含义很简单 就是最终的加密结果是可变的 而非必需按标准MD 加密实现 Java类库security中的MessageDigest类就提供了MD 加密的支持 实现起来非常方便 为了实现更多效果 我们可以如下设计MD 工具类

    Java代码

    package ** ** util;

    import java security MessageDigest;

    /**

    * 标准MD 加密方法 使用java类库的security包的MessageDigest类处理

    * @author Sarin

    */

    public class MD {

    /**

    * 获得MD 加密密码的方法

    */

    public static String getMD ofStr(String origString) {

    String origMD = null;

    try {

    MessageDigest md = MessageDigest getInstance( MD );

    byte[] result = md digest(origString getBytes());

    origMD = byteArray HexStr(result);

    } catch (Exception e) {

    e printStackTrace();

    }

    return origMD ;

    }

    /**

    * 处理字节数组得到MD 密码的方法

    */

    private static String byteArray HexStr(byte[] bs) {

    StringBuffer *** = new StringBuffer();

    for (byte b : bs) {

    *** append(byte HexStr(b));

    }

    return *** toString();

    }

    /**

    * 字节标准移位转十六进制方法

    */

    private static String byte HexStr(byte b) {

    String hexStr = null;

    int n = b;

    if (n < ) {

    //若需要自定义加密 请修改这个移位算法即可

    n = b & x F + ;

    }

    hexStr = Integer toHexString(n / ) + Integer toHexString(n % );

    return hexStr toUpperCase();

    }

    /**

    * 提供一个MD 多次加密方法

    */

    public static String getMD ofStr(String origString int times) {

    String md = getMD ofStr(origString);

    for (int i = ; i < times ; i++) {

    md = getMD ofStr(md );

    }

    return getMD ofStr(md );

    }

    /**

    * 密码验证方法

    */

    public static boolean verifyPassword(String inputStr String MD Code) {

    return getMD ofStr(inputStr) equals(MD Code);

    }

    /**

    * 重载一个多次加密时的密码验证方法

    */

    public static boolean verifyPassword(String inputStr String MD Code int times) {

    return getMD ofStr(inputStr times) equals(MD Code);

    }

    /**

    * 提供一个测试的主函数

    */

    public static void main(String[] args) {

    System out println( : + getMD ofStr( ));

    System out println( : + getMD ofStr( ));

    System out println( sarin: + getMD ofStr( sarin ));

    System out println( : + getMD ofStr( ));

    }

    }

    可以看出实现的过程非常简单 因为由java类库提供了处理支持 但是要清楚的是这种方式产生的密码不是标准的MD 码 它需要进行移位处理才能得到标准MD 码 这个程序的关键之处也在这了 怎么可变?调整移位算法不就可变了么!不进行移位 也能够得到 位的密码 这就不是标准加密了 只要加密和验证过程使用相同的算法就可以了

    MD 加密还是很安全的 像CMD 那些穷举破解的只是针对标准MD 加密的结果进行的 如果自定义移位算法后 它还有效么?可以说是无解的了 所以MD 非常安全可靠

    为了更可变 还提供了多次加密的方法 可以在MD 基础之上继续MD 就是对 位的第一次加密结果再MD 恩 这样去破解?没有任何意义

    这样在MIS系统中使用 安全可靠 欢迎交流 希望对使用者有用

    我们最后看看由MD 加密算法实现的类 那是非常庞大的

    Java代码

    import java lang reflect *;

    /**

    * **********************************************

    * md 类实现了RSA Data Security Inc 在提交给IETF

    * 的RFC 中的MD message digest 算法

    * ***********************************************

    */

    public class MD {

    /* 下面这些S S 实际上是一个 * 的矩阵 在原始的C实现中是用#define 实现的

    这里把它们实现成为static final是表示了只读 切能在同一个进程空间内的多个

    Instance间共享*/

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final int S = ;

    static final byte[] PADDING = {

    };

    /* 下面的三个成员是MD 计算过程中用到的 个核心数据 在原始的C实现中

    被定义到MD _CTX结构中

    */

    private long[] state = new long[ ]; // state (ABCD)

    private long[] count = new long[ ]; // number of bits molo ^ (l *** first)

    private byte[] buffer = new byte[ ]; // input buffer

    /* digestHexStr是MD 的唯一一个公共成员 是最新一次计算结果的

    进制ASCII表示

    */

    public String digestHexStr;

    /* digest 是最新一次计算结果的 进制内部表示 表示 bit的MD 值

    */

    private byte[] digest = new byte[ ];

    /*

    getMD ofStr是类MD 最主要的公共方法 入口参数是你想要进行MD 变换的字符串

    返回的是变换完的结果 这个结果是从公共成员digestHexStr取得的.

    */

    public String getMD ofStr(String inbuf) {

    md Init();

    md Update(inbuf getBytes() inbuf length());

    md Final();

    digestHexStr = ;

    for (int i = ; i < ; i++) {

    digestHexStr += byteHEX(digest[i]);

    }

    return digestHexStr;

    }

    // 这是MD 这个类的标准构造函数 JavaBean要求有一个public的并且没有参数的构造函数

    public MD () {

    md Init();

    return;

    }

    /* md Init是一个初始化函数 初始化核心变量 装入标准的幻数 */

    private void md Init() {

    count[ ] = L;

    count[ ] = L;

    ///* Load magic initialization constants

    state[ ] = x L;

    state[ ] = xefcdab L;

    state[ ] = x badcfeL;

    state[ ] = x L;

    return;

    }

    /* F G H I 是 个基本的MD 函数 在原始的MD 的C实现中 由于它们是

    简单的位运算 可能出于效率的考虑把它们实现成了宏 在java中 我们把它们

    实现成了private方法 名字保持了原来C中的 */

    private long F(long x long y long z) {

    return (x & y) | ((~x) & z);

    }

    private long G(long x long y long z) {

    return (x & z) | (y & (~z));

    }

    private long H(long x long y long z) {

    return x ^ y ^ z;

    }

    private long I(long x long y long z) {

    return y ^ (x | (~z));

    }

    /*

    FF GG HH和II将调用F G H I进行近一步变换

    FF GG HH and II transformations for rounds and

    Rotation is separate from addition to prevent reputation

    */

    private long FF(long a long b long c long d long x long s long ac) {

    a += F(b c d) + x + ac;

    a = ((int) a << s) | ((int) a >>> ( s));

    a += b;

    return a;

    }

    private long GG(long a long b long c long d long x long s long ac) {

    a += G(b c d) + x + ac;

    a = ((int) a << s) | ((int) a >>> ( s));

    a += b;

    return a;

    }

    private long HH(long a long b long c long d long x long s long ac) {

    a += H(b c d) + x + ac;

    a = ((int) a << s) | ((int) a >>> ( s));

    a += b;

    return a;

    }

    private long II(long a long b long c long d long x long s long ac) {

    a += I(b c d) + x + ac;

    a = ((int) a << s) | ((int) a >>> ( s));

    a += b;

    return a;

    }

    /*

    md Update是MD 的主计算过程 inbuf是要变换的字节串 inputlen是长度 这个

    函数由getMD ofStr调用 调用之前需要调用md init 因此把它设计成private的

    */

    private void md Update(byte[] inbuf int inputLen) {

    int i index partLen;

    byte[] block = new byte[ ];

    index = (int) (count[ ] >>> ) & x F;

    // /* Update number of bits */

    if ((count[ ] += (inputLen << )) < (inputLen << ))

    count[ ]++;

    count[ ] += (inputLen >>> );

    partLen = index;

    // Transform as many times as possible

    if (inputLen >= partLen) {

    md Memcpy(buffer inbuf index partLen);

    md Transform(buffer);

    for (i = partLen; i + < inputLen; i += ) {

    md Memcpy(block inbuf i );

    md Transform(block);

    }

    index = ;

    } else

    i = ;

    ///* Buffer remaining input */

    md Memcpy(buffer inbuf index i inputLen i);

    }

    /*

    md Final整理和填写输出结果

    */

    private void md Final() {

    byte[] bits = new byte[ ];

    int index padLen;

    ///* Save number of bits */

    Encode(bits count );

    ///* Pad out to mod

    index = (int) (count[ ] >>> ) & x f;

    padLen = (index < ) ? ( index) : ( index);

    md Update(PADDING padLen);

    ///* Append length (before padding) */

    md Update(bits );

    ///* Store state in digest */

    Encode(digest state );

    }

    /* md Memcpy是一个内部使用的byte数组的块拷贝函数 从input的inpos开始把len长度的

    字节拷贝到output的outpos位置开始

    */

    private void md Memcpy(byte[] output byte[] input int outpos int inpos int len) {

    int i;

    for (i = ; i < len; i++)

    output[outpos + i] = input[inpos + i];

    }

    /*

    md Transform是MD 核心变换程序 有md Update调用 block是分块的原始字节

    */

    private void md Transform(byte block[]) {

    long a = state[ ] b = state[ ] c = state[ ] d = state[ ];

    long[] x = new long[ ];

    Decode(x block );

    /* Round */

    a = FF(a b c d x[ ] S xd aa L); /* */

    d = FF(d a b c x[ ] S xe c b L); /* */

    c = FF(c d a b x[ ] S x dbL); /* */

    b = FF(b c d a x[ ] S xc bdceeeL); /* */

    a = FF(a b c d x[ ] S xf c fafL); /* */

    d = FF(d a b c x[ ] S x c aL); /* */

    c = FF(c d a b x[ ] S xa L); /* */

    b = FF(b c d a x[ ] S xfd L); /* */

    a = FF(a b c d x[ ] S x d L); /* */

    d = FF(d a b c x[ ] S x b f afL); /* */

    c = FF(c d a b x[ ] S xffff bb L); /* */

    b = FF(b c d a x[ ] S x cd beL); /* */

    a = FF(a b c d x[ ] S x b L); /* */

    d = FF(d a b c x[ ] S xfd L); /* */

    c = FF(c d a b x[ ] S xa eL); /* */

    b = FF(b c d a x[ ] S x b L); /* */

    /* Round */

    a = GG(a b c d x[ ] S xf e L); /* */

    d = GG(d a b c x[ ] S xc b L); /* */

    c = GG(c d a b x[ ] S x e a L); /* */

    b = GG(b c d a x[ ] S xe b c aaL); /* */

    a = GG(a b c d x[ ] S xd f dL); /* */

    d = GG(d a b c x[ ] S x L); /* */

    c = GG(c d a b x[ ] S xd a e L); /* */

    b = GG(b c d a x[ ] S xe d fbc L); /* */

    a = GG(a b c d x[ ] S x e cde L); /* */

    d = GG(d a b c x[ ] S xc d L); /* */

    c = GG(c d a b x[ ] S xf d d L); /* */

    b = GG(b c d a x[ ] S x a edL); /* */

    a = GG(a b c d x[ ] S xa e e L); /* */

    d = GG(d a b c x[ ] S xfcefa f L); /* */

    c = GG(c d a b x[ ] S x f d L); /* */

    b = GG(b c d a x[ ] S x d a c aL); /* */

    /* Round */

    a = HH(a b c d x[ ] S xfffa L); /* */

    d = HH(d a b c x[ ] S x f L); /* */

    c = HH(c d a b x[ ] S x d d L); /* */

    b = HH(b c d a x[ ] S xfde cL); /* */

    a = HH(a b c d x[ ] S xa beea L); /* */

    d = HH(d a b c x[ ] S x bdecfa L); /* */

    c = HH(c d a b x[ ] S xf bb b L); /* */

    b = HH(b c d a x[ ] S xbebfbc L); /* */

    a = HH(a b c d x[ ] S x b ec L); /* */

    d = HH(d a b c x[ ] S xeaa faL); /* */

    c = HH(c d a b x[ ] S xd ef L); /* */

    b = HH(b c d a x[ ] S x d L); /* */

    a = HH(a b c d x[ ] S xd d d L); /* */

    d = HH(d a b c x[ ] S xe db e L); /* */

    c = HH(c d a b x[ ] S x fa cf L); /* */

    b = HH(b c d a x[ ] S xc ac L); /* */

    /* Round */

    a = II(a b c d x[ ] S xf L); /* */

    d = II(d a b c x[ ] S x aff L); /* */

    c = II(c d a b x[ ] S xab a L); /* */

    b = II(b c d a x[ ] S xfc a L); /* */

    a = II(a b c d x[ ] S x b c L); /* */

    d = II(d a b c x[ ] S x f ccc L); /* */

    c = II(c d a b x[ ] S xffeff dL); /* */

    b = II(b c d a x[ ] S x dd L); /* */

    a = II(a b c d x[ ] S x fa e fL); /* */

    d = II(d a b c x[ ] S xfe ce e L); /* */

    c = II(c d a b x[ ] S xa L); /* */

    b = II(b c d a x[ ] S x e a L); /* */

    a = II(a b c d x[ ] S xf e L); /* */

    d = II(d a b c x[ ] S xbd af L); /* */

    c = II(c d a b x[ ] S x ad d bbL); /* */

    b = II(b c d a x[ ] S xeb d L); /* */

    state[ ] += a;

    state[ ] += b;

    state[ ] += c;

    state[ ] += d;

    }

    /*Encode把long数组按顺序拆成byte数组 因为java的long类型是 bit的

    只拆低 bit 以适应原始C实现的用途

    */

    private void Encode(byte[] output long[] input int len) {

    int i j;

    for (i = j = ; j < len; i++ j += ) {

    output[j] = (byte) (input[i] & xffL);

    output[j + ] = (byte) ((input[i] >>> ) & xffL);

    output[j + ] = (byte) ((input[i] >>> ) & xffL);

    output[j + ] = (byte) ((input[i] >>> ) & xffL);

    }

    }

    /*Decode把byte数组按顺序合成成long数组 因为java的long类型是 bit的

    只合成低 bit 高 bit清零 以适应原始C实现的用途

    */

    private void Decode(long[] output byte[] input int len) {

    int i j;

    for (i = j = ; j < len; i++ j += )

    output[i] = b iu(input[j]) | (b iu(input[j + ]) << ) | (b iu(input[j + ]) << )

    | (b iu(input[j + ]) << );

    return;

    }

    /*

    b iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序 因为java没有unsigned运算

    */

    public static long b iu(byte b) {

    return b < ? b & x F + : b;

    }

    /*byteHEX() 用来把一个byte类型的数转换成十六进制的ASCII表示

    因为java中的byte的toString无法实现这一点 我们又没有C语言中的

    sprintf(outbuf % X ib)

    */

    public static String byteHEX(byte ib) {

    char[] Digit = { A B C D E F };

    char[] ob = new char[ ];

    ob[ ] = Digit[(ib >>> ) & X F];

    ob[ ] = Digit[ib & X F];

    String s = new String(ob);

    return s;

    }

    public static void main(String args[]) {

    MD m = new MD ();

    if (Array getLength(args) == ) { //如果没有参数 执行标准的Test Suite

    System out println( MD Test suite: );

    System out println( MD ( ): + m getMD ofStr( ));

    System out println( MD ( a ): + m getMD ofStr( a ));

    System out println( MD ( abc ): + m getMD ofStr( abc ));

    System out println( MD ( ): + m getMD ofStr( ));

    System out println( MD ( ): + m getMD ofStr( ));

    System out println( MD ( message digest ): + m getMD ofStr( message digest ));

    System out println( MD ( abcdefghijklmnopqrstuvwxyz ): + m getMD ofStr( abcdefghijklmnopqrstuvwxyz ));

    System out println( MD ( ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ):

    + m getMD ofStr( ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ));

    } else

    System out println( MD ( + args[ ] + )= + m getMD ofStr(args[ ]));

    }

    lishixin/Article/program/Java/hx/201311/26604

      如何使用Java生成MD5代码

      这是我以前做的一个小项目时用到md5写的

      import java.security.MessageDigest;

      import java.security.NoSuchAlgorithmException;

      //将用户密码进行md5加密   并返回加密后的32位十六进制密码

      public class MD5Util {

      public static String md5(String password) {

      try {

      // 获取md5对象

      MessageDigest md = MessageDigest.getInstance("md5");

      // 获取加密后的密码并返回十进制字节数组

      byte[] bytes = md.digest(password.getBytes());

      // 遍历数组得到每个十进制数并转换成十六进制

      StringBuffer sb = new StringBuffer();

      for (byte b : bytes) {

      // 把每个数转成十六进制 存进字符中

      sb.append(toHex(b));

      }

      String finish = sb.toString();

      return finish;

      } catch (NoSuchAlgorithmException e) {

      e.printStackTrace();

      throw new RuntimeException(e);

      }

      }

      // 十进制转十六进制方法

      private static String toHex(byte b) {

      int target = 0;

      if (b < 0) {

      target = 255 + b;

      } else {

      target = b;

      }

      int first = target / 16;

      int second = target % 16;

      return Hex[first] + Hex[second];

      }

      static String[] Hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",

      "a", "b", "c", "d", "e", "f" };

      /*public static void main(String[] args) {

      String a = MD5Util.md5("1234");

      System.out.println(a);

      }*/

      }

      MD5算法原理及实现

      散列函数,也称作哈希函数,消息摘要函数,单向函数或者杂凑函数。散列函数主要用于验证数据的完整性。通过散列函数,可以创建消息的“数字指纹”,消息接收方可以通过校验消息的哈希值来验证消息的完整性,防止消息被篡改。散列函数具有以下特性:

      任何消息经过散列函数处理后,都会产生一个唯一的散列值,这个散列值可以用来验证消息的完整性。计算消息散列值的过程被称为“消息摘要”,计算消息散列值的算法被称为消息摘要算法。常使用的消息摘要算法有:MD—消息摘要算法,SHA—安全散列算法,MAC—消息认证码算法。本文主要来了解MD算法。

      MD5算法是典型的消息摘要算法,它是由MD4,MD3和MD2算法演变而来。无论是哪一种MD算法,其原理都是接受一个任意长度的消息并产生一个128位的消息摘要。如果把得到的消息摘要转换成十六进制字符串,则会得到一个32字节长度的字符串,我们平常见到的大部分MD数字指纹就是一个长度为32的十六进制字符串。

      假设原始消息长度是b(以bit为单位),注意这里b可以是任意长度,并不一定要是8的整数倍。计算该消息MD5值的过程如下:

      在计算消息的MD5值之前,首先对原始信息进行填充,这里的信息填充分为两步。

      第一步,对原始信息进行填充,填充之后,要求信息的长度对512取余等于448。填充的规则如下:假设原始信息长度为b bit,那么在信息的b+1 bit位填充1,剩余的位填充0,直到信息长度对512取余为448。这里有一点需要注意,如果原始信息长度对512取余正好等于448,这种情况仍然要进行填充,很明显,在这时我们要填充的信息长度是512位,直到信息长度对512取余再次等于448。所以,填充的位数最少为1,最大为512。

      第二步,填充信息长度,我们需要把原始信息长度转换成以bit为单位,然后在第一步操作的结果后面填充64bit的数据表示原始信息长度。第一步对原始信息进行填充之后,信息长度对512取余结果为448,这里再填充64bit的长度信息,整个信息恰好可以被512整除。其实从后续过程可以看到,计算MD5时,是将信息分为若干个分组进行处理的,每个信息分组的长度是512bit。

      在进行MD5值计算之前,我们先来做一些定义。

      下面就是最核心的信息处理过程,计算MD5的过程实际上就是轮流处理每个信息分组的过程。

      MD5算法实现如下所示。

      这里也和Java提供的标准MD5算法进行了对比,通过测试可以看到该MD5计算的结果和Java标准MD5算法的计算结果是一样的。

      Top