java生成MD5校验码及算法实现

 

    在Java中,java.security.MessageDigest (rt.jar中)已经定义了 MD5 的计算,所以我们只需要简单地调用即可得到 MD5 的128 位整数。然后将此 128 位计 16 个字节转换成 16 进制表示即可。 

 

    下面是一个可生成字符串或文件MD5校验码的例子,测试过,可当做工具类直接使用,其中最主要的是getMD5String(String s)和getFileMD5String(File file)两个方法,分别用于生成字符串的md5校验值和生成文件的md5校验值,getFileMD5String_old(File file)方法可删除,不建议使用:

 

Java代码
  1. package com.why.md5;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.nio.MappedByteBuffer;  
  8. import java.nio.channels.FileChannel;  
  9. import java.security.MessageDigest;  
  10. import java.security.NoSuchAlgorithmException;  
  11.   
  12. public class MD5Util {  
  13.     /** 
  14.      * 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合 
  15.      */  
  16.     protected static char hexDigits[] = { '0''1''2''3''4''5''6',  
  17.             '7''8''9''a''b''c''d''e''f' };  
  18.   
  19.     protected static MessageDigest messagedigest = null;  
  20.     static {  
  21.         try {  
  22.             messagedigest = MessageDigest.getInstance("MD5");  
  23.         } catch (NoSuchAlgorithmException nsaex) {  
  24.             System.err.println(MD5Util.class.getName()  
  25.                     + "初始化失败,MessageDigest不支持MD5Util。");  
  26.             nsaex.printStackTrace();  
  27.         }  
  28.     }  
  29.       
  30.     /** 
  31.      * 生成字符串的md5校验值 
  32.      *  
  33.      * @param s 
  34.      * @return 
  35.      */  
  36.     public static String getMD5String(String s) {  
  37.         return getMD5String(s.getBytes());  
  38.     }  
  39.       
  40.     /** 
  41.      * 判断字符串的md5校验码是否与一个已知的md5码相匹配 
  42.      *  
  43.      * @param password 要校验的字符串 
  44.      * @param md5PwdStr 已知的md5校验码 
  45.      * @return 
  46.      */  
  47.     public static boolean checkPassword(String password, String md5PwdStr) {  
  48.         String s = getMD5String(password);  
  49.         return s.equals(md5PwdStr);  
  50.     }  
  51.       
  52.     /** 
  53.      * 生成文件的md5校验值 
  54.      *  
  55.      * @param file 
  56.      * @return 
  57.      * @throws IOException 
  58.      */  
  59.     public static String getFileMD5String(File file) throws IOException {         
  60.         InputStream fis;  
  61.         fis = new FileInputStream(file);  
  62.         byte[] buffer = new byte[1024];  
  63.         int numRead = 0;  
  64.         while ((numRead = fis.read(buffer)) > 0) {  
  65.             messagedigest.update(buffer, 0, numRead);  
  66.         }  
  67.         fis.close();  
  68.         return bufferToHex(messagedigest.digest());  
  69.     }  
  70.   
  71.     /** 
  72.      * JDK1.4中不支持以MappedByteBuffer类型为参数update方法,并且网上有讨论要慎用MappedByteBuffer, 
  73.      * 原因是当使用 FileChannel.map 方法时,MappedByteBuffer 已经在系统内占用了一个句柄, 
  74.      * 而使用 FileChannel.close 方法是无法释放这个句柄的,且FileChannel有没有提供类似 unmap 的方法, 
  75.      * 因此会出现无法删除文件的情况。 
  76.      *  
  77.      * 不推荐使用 
  78.      *  
  79.      * @param file 
  80.      * @return 
  81.      * @throws IOException 
  82.      */  
  83.     public static String getFileMD5String_old(File file) throws IOException {  
  84.         FileInputStream in = new FileInputStream(file);  
  85.         FileChannel ch = in.getChannel();  
  86.         MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,  
  87.                 file.length());  
  88.         messagedigest.update(byteBuffer);  
  89.         return bufferToHex(messagedigest.digest());  
  90.     }  
  91.   
  92.     public static String getMD5String(byte[] bytes) {  
  93.         messagedigest.update(bytes);  
  94.         return bufferToHex(messagedigest.digest());  
  95.     }  
  96.   
  97.     private static String bufferToHex(byte bytes[]) {  
  98.         return bufferToHex(bytes, 0, bytes.length);  
  99.     }  
  100.   
  101.     private static String bufferToHex(byte bytes[], int m, int n) {  
  102.         StringBuffer stringbuffer = new StringBuffer(2 * n);  
  103.         int k = m + n;  
  104.         for (int l = m; l < k; l++) {  
  105.             appendHexPair(bytes[l], stringbuffer);  
  106.         }  
  107.         return stringbuffer.toString();  
  108.     }  
  109.   
  110.     private static void appendHexPair(byte bt, StringBuffer stringbuffer) {  
  111.         char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换, >>> 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同   
  112.         char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换   
  113.         stringbuffer.append(c0);  
  114.         stringbuffer.append(c1);  
  115.     }  
  116.       
  117.     public static void main(String[] args) throws IOException {  
  118.         long begin = System.currentTimeMillis();  
  119.   
  120.         File file = new File("C:/12345.txt");  
  121.         String md5 = getFileMD5String(file);  
  122.   
  123. //      String md5 = getMD5String("a");  
  124.           
  125.         long end = System.currentTimeMillis();  
  126.         System.out.println("md5:" + md5 + " time:" + ((end - begin) / 1000) + "s");  
  127.     }  
  128. }  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值