之前在工作中需要使用MD5来判断APK是否是同一个文件,开始服务端和客户端使用MD5的方式是没有问题的,但是随着APK文件越来越多,有一天忽然发现同一个APK客户端和服务端计算的MD5值不相同,导致APK上传失败问题,经过仔细排查,发现客户端生成的MD5少了一位,客户端一直采用如下的方式计算.

BigIntegerbigInt=newBigInteger(1,digest.digest());bigInt.toString(16);

这种方式来计算,后来通过验证发现,大部分时间这种方式是没问题的,但是当遇到第一位数字是0时,就会发现得到的MD5把首位的0丢掉啦(很隐蔽的一个坑呀),原因是bigint进行16进制转换的时候第一个0被自动去掉了

所以不建议使用这种方式来计算一个文件的MD5,可以使用下面的方式:

publicclassMD5Util{protectedstaticcharhexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};publicsynchronizedstaticStringgetAgentMD5(Stringpath){Filefile=newFile(path);if(!file.exists()||!file.isFile()){System.out.println("文件不存在");returnnull;}MessageDigestdigest=null;FileInputStreamfis=null;try{digest=MessageDigest.getInstance("MD5");fis=newFileInputStream(file);byte[]buffer=newbyte[1024];intnumRead=0;while((numRead=fis.read(buffer))>0){digest.update(buffer,0,numRead);}fis.close();}catch(Exceptione){//TODO:handleexception}returnbufferToHex(digest.digest());}privatestaticStringbufferToHex(bytebytes[]){returnbufferToHex(bytes,0,bytes.length);}privatestaticStringbufferToHex(bytebytes[],intm,intn){StringBufferstringbuffer=newStringBuffer(2*n);intk=m+n;for(intl=m;l<k;l++){appendHexPair(bytes[l],stringbuffer);}returnstringbuffer.toString();}privatestaticvoidappendHexPair(bytebt,StringBufferstringbuffer){charc0=hexDigits[(bt&0xf0)>>4];//取字节中高4位的数字转换,charc1=hexDigits[bt&0xf];//取字节中低4位的数字转换stringbuffer.append(c0);stringbuffer.append(c1);}publicstaticvoidmain(String[]args){}