commons-codec包可以从apache下载:http://commons.apache.org/codec/download_codec.cgi
MD5现在是用来作为一种数字签名算法,即A向B发送数据m,为了让B确信数据是A送来的并且没有被篡改于是A就是用hash算法将数据散列一并发送给 B。B接收到文件以后也用相同的hash算法校验数据是否被修改。主要是防止数据被修改的。MD5值的重复就是所谓的碰撞。
获取文件的MD5码:
System.out.println(DigestUtils.md5Hex(new FileInputStream(new File("C:/ttt/new1328505655521"))));
获取字符串MD5码:
System.out.println(DigestUtils.md5Hex(string));
22222222222222222222
今天在这个问题上花费了一部分时间,起初,自己借别人的类,在Android项目中采用Java应用md5校验文件发现和在linux下采用命令md5sum校验文件结果不一致。
这个问题,太惊奇了!
最后直接下结果吧:
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class TestMD5 {
public static String md5( byte[] key) {
String cacheKey;
try {
final MessageDigest mDigest = MessageDigest.getInstance("MD5");
mDigest.update(key);
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode());
}
return cacheKey;
}
private static String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
private static byte[] getBytes(String filePath){
byte[] buffer = null;
try {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String path = "D:\\Android\\Test.apk";
String md5Value = md5(getBytes(path));
System.out.println("md5Value =====" + md5Value);
}
}
Linux上验证后,发现结果一致了,先简单记录下,后面在详细深入研究,并下文档记录。
3333333333333333333333333
MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改。MD5全称是报文摘要算法(Message-Digest Algorithm
5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的“指纹”(或称“报文摘要”),不同的文件产生相同的报文摘要的可能性是非常非常之小的。
在linux或Unix上,md5sum是用来计算和校验文件报文摘要的工具程序。一般来说,安装了Linux后,就会有md5sum这个工具,直接在命令行终端直接运行。
使用md5sum来产生指纹(报文摘要)命令如下:
md5sum file > file.md5
或者
md5sum file >>file.md5
也可以把多个文件的报文摘要输出到一个md5文件中,这要使用通配符*,比如某目录下有几个iso文件,要把这几个iso文件的摘要输出到iso.md5文件中,命令如下:
md5sum *.iso > iso.md5
2、使用md5报文摘要验证文件,方法有二:
把下载的文件file和该文件的file.md5报文摘要文件放在同一个目录下,然后用如下命令进行验证:
md5sum -c file.md5
然后如果验证成功,则会输出:正确
md5sum passwd passwd.bak /etc/passwd
--------------------------------------
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
/*
* 传入一个字符串String msg,返回Java MD5加密后的16进制的字符串结果。
* 结果形如:c0e84e870874dd37ed0d164c7986f03a
*/
public static String getMD5(String msg) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
md.reset();
md.update(msg.getBytes());
byte[] bytes = md.digest();
String result = "";
for (byte b : bytes) {
// byte转换成16进制
result += String.format("%02x", b);
}
return result;
}
// 测试
// public static void main(String[] args) {
// String msg = "hello,world!";
// System.out.println(getMD5(msg));
// }
}
------------------------------
444444444444444444444
import java.security.MessageDigest; /**
* Md5 工具
*/
public class Md5Util { private static MessageDigest md5 = null;
static {
try {
md5 = MessageDigest.getInstance("MD5");
} catch (Exception e) {
System.out.println(e.getMessage());
}
} /**
* 用于获取一个String的md5值
* @param string
* @return
*/
public static String getMd5(String str) {
byte[] bs = md5.digest(str.getBytes());
StringBuilder sb = new StringBuilder(40);
for(byte x:bs) {
if((x & 0xff)>>4 == 0) {
sb.append("0").append(Integer.toHexString(x & 0xff));
} else {
sb.append(Integer.toHexString(x & 0xff));
}
}
return sb.toString();
} public static void main(String[] args) {
System.out.println(getMd5("hello world"));
}
}
for(i=0;i<len;i++)
output[outpos+i]=input[inpos+i];
}
void trans (byte block[]){
long a=state[0],b=state[1],c=state[2],d=state[3];
long[] x = new long[16];
Decode (x, block, 64);
a = X1 (a, b, c, d, x[0], S11,0xd76aa478L);//1
d = X1 (d, a, b, c, x[1], S12,0xe8c7b756L);
c = X1 (c, d, a, b, x[2], S13,0x242070dbL);
b = X1 (b, c, d, a, x[3], S14,0xc1bdceeeL);
a = X1 (a, b, c, d, x[4], S11,0xf57c0fafL);
d = X1 (d, a, b, c, x[5], S12,0x4787c62aL);
c = X1 (c, d, a, b, x[6], S13,0xa8304613L);
b = X1 (b, c, d, a, x[7], S14,0xfd469501L);
a = X1 (a, b, c, d, x[8], S11,0x698098d8L);
d = X1 (d, a, b, c, x[9], S12,0x8b44f7afL);//10
c = X1 (c, d, a, b, x[10],S13,0xffff5bb1L);
b = X1 (b, c, d, a, x[11],S14,0x895cd7beL);
a = X1 (a, b, c, d, x[12],S11,0x6b901122L);
d = X1 (d, a, b, c, x[13],S12,0xfd987193L);
c = X1 (c, d, a, b, x[14],S13,0xa679438eL);
b = X1 (b, c, d, a, x[15],S14,0x49b40821L);
a = X2 (a, b, c, d, x[1], S21,0xf61e2562L);
d = X2 (d, a, b, c, x[6], S22,0xc040b340L);
c = X2 (c, d, a, b, x[11],S23,0x265e5a51L);
b = X2 (b, c, d, a, x[0], S24,0xe9b6c7aaL);//20
a = X2 (a, b, c, d, x[5], S21,0xd62f105dL);
d = X2 (d, a, b, c, x[10],S22,0x02441453L);
c = X2 (c, d, a, b, x[15],S23,0xd8a1e681L);
b = X2 (b, c, d, a, x[4], S24,0xe7d3fbc8L);
a = X2 (a, b, c, d, x[9], S21,0x21e1cde6L);
d = X2 (d, a, b, c, x[14],S22,0xc33707d6L);
c = X2 (c, d, a, b, x[3], S23,0xf4d50d87L);
b = X2 (b, c, d, a, x[8], S24,0x455a14edL);
a = X2 (a, b, c, d, x[13],S21,0xa9e3e905L);
d = X2 (d, a, b, c, x[2], S22,0xfcefa3f8L);//30
c = X2 (c, d, a, b, x[7], S23,0x676f02d9L);
b = X2 (b, c, d, a, x[12],S24,0x8d2a4c8aL);
a = X3 (a, b, c, d, x[5], S31,0xfffa3942L);
d = X3 (d, a, b, c, x[8], S32,0x8771f681L);
c = X3 (c, d, a, b, x[11],S33,0x6d9d6122L);
b = X3 (b, c, d, a, x[14],S34,0xfde5380cL);
a = X3 (a, b, c, d, x[1], S31,0xa4beea44L);
d = X3 (d, a, b, c, x[4], S32,0x4bdecfa9L);
c = X3 (c, d, a, b, x[7], S33,0xf6bb4b60L);
b = X3 (b, c, d, a, x[10],S34,0xbebfbc70L);//40
a = X3 (a, b, c, d, x[13],S31,0x289b7ec6L);
d = X3 (d, a, b, c, x[0], S32,0xeaa127faL);
c = X3 (c, d, a, b, x[3], S33,0xd4ef3085L);
b = X3 (b, c, d, a, x[6], S34,0x04881d05L);
a = X3 (a, b, c, d, x[9], S31,0xd9d4d039L);
d = X3 (d, a, b, c, x[12],S32,0xe6db99e5L);
c = X3 (c, d, a, b, x[15],S33,0x1fa27cf8L);
b = X3 (b, c, d, a, x[2], S34,0xc4ac5665L);
a = X4 (a, b, c, d, x[0], S41,0xf4292244L);
d = X4 (d, a, b, c, x[7], S42,0x432aff97L);//50
c = X4 (c, d, a, b, x[14],S43,0xab9423a7L);
b = X4 (b, c, d, a, x[5], S44,0xfc93a039L);
a = X4 (a, b, c, d, x[12],S41,0x655b59c3L);
d = X4 (d, a, b, c, x[3], S42,0x8f0ccc92L);
c = X4 (c, d, a, b, x[10],S43,0xffeff47dL);
b = X4 (b, c, d, a, x[1], S44,0x85845dd1L);
a = X4 (a, b, c, d, x[8], S41,0x6fa87e4fL);
d = X4 (d, a, b, c, x[15],S42,0xfe2ce6e0L);
c = X4 (c, d, a, b, x[6], S43,0xa3014314L);
b = X4 (b, c, d, a, x[13],S44,0x4e0811a1L);//60
a = X4 (a, b, c, d, x[4], S41,0xf7537e82L);
d = X4 (d, a, b, c, x[11],S42,0xbd3af235L);
c = X4 (c, d, a, b, x[2], S43,0x2ad7d2bbL);
b = X4 (b, c, d, a, x[9], S44,0xeb86d391L);
state[0]+=a;state[1]+=b;state[2]+=c;state[3]+=d;
}
void Encode(byte[] output,long[] input,int len){
int i, j;
for (i = 0, j = 0; j < len; i++, j += 4){
output[j] = (byte)(input[i] & 0xffL);
output[j+1]=(byte)((input[i]>>> 8) & 0xffL);
output[j+2]=(byte)((input[i]>>>16) & 0xffL);
output[j+3]=(byte)((input[i]>>>24) & 0xffL);
}
}
void Decode(long[] output,byte[] input,int len){
int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i]=liu(input[j])|(liu(input[j+1])<<8)|
(liu(input[j+2])<<16)|(liu(input[j+3])<<24);
}
static long liu(byte b){return b<0?b&0x7F+128:b;}
static String bx(byte ib){
char[]
Digit={'0','1','2','3','4','5','6','7','8','9','a'
,'b','c','d','e','f'};
char [] ob = new char[2];
ob[0] = Digit[(ib >>> 4) & 0X0F];
ob[1] = Digit[ib & 0X0F];
return (new String(ob));
}
}