java MD5加密代码工具类

本文详细介绍了MD5Util类在Java中如何实现MD5哈希算法,包括初始化、更新输入、最终整理和填充输出结果的过程,展示了核心的位运算和变换函数。
摘要由CSDN通过智能技术生成

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

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

  • 被定义到MD5_CTX结构中

*/

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

private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb first)

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

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

  • 16进制ASCII表示.

*/

public String digestHexStr;

/** digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值.

*/

private byte[] digest = new byte[16];

/** getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串

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

*/

public String getMD5ofStr(String inbuf) {

md5Init();

md5Update(inbuf.getBytes(), inbuf.length());

md5Final();

digestHexStr = “”;

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

digestHexStr += byteHEX(digest[i]);

}

return digestHexStr;

}

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

public MD5Util() {

md5Init();

return;

}

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

*/

private void md5Init() {

count[0] = 0L;

count[1] = 0L;

///* Load magic initialization constants.

state[0] = 0x67452301L;

state[1] = 0xefcdab89L;

state[2] = 0x98badcfeL;

state[3] = 0x10325476L;

return;

}

/** F, G, H ,I 是4个基本的MD5函数,在原始的MD5的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 1, 2, 3, and 4.

  • Rotation is separate from addition to prevent recomputation.

*/

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 >>> (32 - 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 >>> (32 - 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 >>> (32 - 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 >>> (32 - s));

a += b;

return a;

}

/** md5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个

  • 函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private的

*/

private void md5Update(byte[] inbuf, int inputLen) {

int i, index, partLen;

byte[] block = new byte[64];

index = (int)(count[0] >>> 3) & 0x3F;

// /* Update number of bits */

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

count[1]++;

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

partLen = 64 - index;

// Transform as many times as possible.

if (inputLen >= partLen) {

md5Memcpy(buffer, inbuf, index, 0, partLen);

md5Transform(buffer);

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

md5Memcpy(block, inbuf, 0, i, 64);

md5Transform (block);

}

index = 0;

} else

i = 0;

///* Buffer remaining input */

md5Memcpy(buffer, inbuf, index, i, inputLen - i);

}

/**md5Final整理和填写输出结果

*/

private void md5Final () {

byte[] bits = new byte[8];

int index, padLen;

///* Save number of bits */

Encode (bits, count, 8);

///* Pad out to 56 mod 64.

index = (int)(count[0] >>> 3) & 0x3f;

padLen = (index < 56) ? (56 - index) : (120 - index);

md5Update (PADDING, padLen);

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

md5Update(bits, 8);

///* Store state in digest */

Encode (digest, state, 16);

}

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

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

*/

private void md5Memcpy (byte[] output, byte[] input,int outpos, int inpos, int len){

int i;

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

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

}

/** md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节

*/

private void md5Transform (byte block[]) {

long a = state[0], b = state[1], c = state[2], d = state[3];

long[] x = new long[16];

Decode (x, block, 64);

/* Round 1 */

a = FF (a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */

d = FF (d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */

c = FF (c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */

b = FF (b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */

a = FF (a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */

d = FF (d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */

c = FF (c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */

b = FF (b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */

a = FF (a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */

d = FF (d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */

c = FF (c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */

b = FF (b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */

a = FF (a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */

d = FF (d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */

c = FF (c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */

b = FF (b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */

/* Round 2 */

a = GG (a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */

d = GG (d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */

c = GG (c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */

b = GG (b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */

a = GG (a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */

d = GG (d, a, b, c, x[10], S22, 0x2441453L); /* 22 */

c = GG (c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */

b = GG (b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */

a = GG (a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */

d = GG (d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */

c = GG (c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */

b = GG (b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */

a = GG (a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */

d = GG (d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */

c = GG (c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */

b = GG (b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */

/* Round 3 */

a = HH (a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */

d = HH (d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */

c = HH (c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */

b = HH (b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */

a = HH (a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */

d = HH (d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */

c = HH (c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */

b = HH (b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */

a = HH (a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */

d = HH (d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */

c = HH (c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */

b = HH (b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */

a = HH (a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */

d = HH (d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */

c = HH (c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

写在最后

为了这次面试,也收集了很多的面试题!

以下是部分面试题截图

Java程序员秋招三面蚂蚁金服,我总结了所有面试题,也不过如此
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
,基本涵盖了95%以上Java开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

写在最后

为了这次面试,也收集了很多的面试题!

以下是部分面试题截图

[外链图片转存中…(img-yOh0VHhO-1713105833202)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值