你的位置:首页 > Java教程

[Java教程]Java哈希散列算法简介


Java哈希散列算法简介 - MD5 & SHA-512

在日常的开发工作中,我们常常会碰到这样的一个场景:我们需要有一种可靠的行之有效的方法来检验跟判断数据在传输过程当中的完整性。最常见的一种情况就是当我们传输文件的时候,由于网络故障或者其他的一些因素,可能会出现我们下载下来的文件不完整,这给我们日常的开发和维护带了一些难题;另外的一个较为常用的场景就是:有没有一种行之有效的方法让我们可以很方便的判断服务器上的文件是不是有最新的数据更新,比如我们现在的移动Hybird App开发,我们经常会发布一些client pack的数据更新,那么我们在每次打开App应用的时候就必须先要检验服务器端是否有最新的更新需要下载,以便我们及时使用最新的App功能。

针对于以上这些应用场景,我们最常使用的方法便是使用安全哈希算法MD5根SHA-512,它们具有以下的特点:

 - 唯一性:同一个数据只有同一个哈希值

 -可靠性:两个不同的数据有不同的哈希值 (MD5已被在某些特例下存在相同得值)

 -不可逆性:不可以通过哈希值反推输入的原值

两个算法都具有极高的安全性,但是相比较而言,SHA-512算法拥有更高的安全级别,因此,此算法已被大部分的人所采用。

以下便是这两种算法的具体实现代码:

package com.andycbluo.secure.checksum.util;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class SecureUtil {    private final String SHA512 = "SHA-512";  private static SecureUtil _instance = null;    private SecureUtil() {}    /**   *   * @return   */  public static SecureUtil getInstance() {    return _instance;  }    /**   *   * @param data   * @return   */  public String generateChecksum(String data) {    return generateChecksum(data, SHA512);  }    /**   *   * @param data   * @param algorithom   * @return   */  public String generateChecksum(String data, String algorithom) {    String checksum = null;        try {      MessageDigest instance = MessageDigest.getInstance(algorithom);      instance.update(data.getBytes("UTF-8"));      checksum = convertBytes2String(instance.digest());    } catch (NoSuchAlgorithmException e) {      e.printStackTrace();    } catch (UnsupportedEncodingException e) {      e.printStackTrace();    }        return checksum;  }    /**   *   * @param data   * @return   */  private String convertBytes2String(byte[] data) {    StringBuffer sb = new StringBuffer();    for(int i = 0; i < data.length; i++) {      sb.append(Integer.toString(data[i] & 0xFF + 0x100, 16).substring(1));    }        return sb.toString();  }    /**   *   * @param filePath   * @return   */  public String generateFileChecksum(String filePath) {    return generateFileChecksum(filePath, SHA512);  }    /**   *   * @param filePath   * @param algorithom   * @return   */  public String generateFileChecksum(String filePath, String algorithom) {    String checksum = null;        MessageDigest instance;    try {      instance = MessageDigest.getInstance(algorithom);            InputStream fis = new FileInputStream(new File(filePath));            byte[] blob = new byte[1024];      int numRead;      do {        numRead = fis.read(blob);        if (numRead > 0) {          instance.update(blob, 0, numRead);        }      } while (numRead != -1);            checksum = convertBytes2String(instance.digest());            fis.close();    } catch (NoSuchAlgorithmException e) {      e.printStackTrace();    } catch (FileNotFoundException e) {      e.printStackTrace();    } catch (IOException e) {      e.printStackTrace();    }        return checksum;  }    /**   *   */  static {    _instance = new SecureUtil();  }}

我们可以通过一个简单的用例来窥探MD5根SHA-512的输出结果:

package com.andycbluo.secure.checksum;import com.andycbluo.secure.checksum.util.SecureUtil;public class TestRunner {  private static final String TEST_DATA = "This is a testing data : 123456789";  private static final String FILE_PATH = "<Replace Your File Path Name Here>";    public static void main(String[] args) {    System.out.println("SHA-512 : " + SecureUtil.getInstance().generateChecksum(TEST_DATA));    System.out.println("MD5 : " + SecureUtil.getInstance().generateChecksum(TEST_DATA, "MD5"));        System.out.println("File SHA-512 : " + SecureUtil.getInstance().generateFileChecksum(FILE_PATH));    System.out.println("File MD5 : " + SecureUtil.getInstance().generateFileChecksum(FILE_PATH, "MD5"));  }}

以下就是本地的输出结果: