背景
對於字符串的加密、長度格式化來說,哈希處理是必不可少的,本文就分享一下java實現的哈希工具類。
代碼實現
HashKit.java
package com.utils;
import java.security.MessageDigest;
/**
* 功能說明:哈希工具類
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:28:24
* @version 0.1
*/
public class HashKit {
private static final java.security.SecureRandom random = new java.security.SecureRandom();
private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
private static final char[] CHAR_ARRAY = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
/**
* 功能說明:使用MD5算法對字符串參數進行哈希處理
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:40:32
* @param srcStr 原字符串
* @return 返回md5哈希處理後的字符串
*/
public static String md5(String srcStr){
return hash("MD5", srcStr);
}
/**
* 功能說明:使用sha1算法對字符串參數進行哈希處理
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:49:43
* @param srcStr 原字符串
* @return 返回sha1哈希處理後的字符串
*/
public static String sha1(String srcStr){
return hash("SHA-1", srcStr);
}
/**
* 功能說明:使用sha256算法對字符串參數進行哈希處理
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:55:43
* @param srcStr 原字符串
* @return 返回sha256哈希處理後的字符串
*/
public static String sha256(String srcStr){
return hash("SHA-256", srcStr);
}
/**
* 功能說明:使用sha384算法對字符串參數進行哈希處理
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:57:23
* @param srcStr 原字符串
* @return 返回sha384哈希處理後的字符串
*/
public static String sha384(String srcStr){
return hash("SHA-384", srcStr);
}
/**
* 功能說明:使用sha512算法對字符串參數進行哈希處理
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:58:22
* @param srcStr 原字符串
* @return 返回sha512哈希處理後的字符串
*/
public static String sha512(String srcStr){
return hash("SHA-512", srcStr);
}
/**
* 功能說明:對原字符串使用指定加密算法進行哈希處理
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:39:24
* @param algorithm 加密算法
* @param srcStr 原字符串
* @return 返回哈希處理後的字符串
*/
public static String hash(String algorithm, String srcStr) {
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
return toHex(bytes);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 功能說明:把字節數組轉爲16進制字符串
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:34:48
* @param bytes
* @return
*/
private static String toHex(byte[] bytes) {
StringBuilder ret = new StringBuilder(bytes.length * 2);
for (int i=0; i<bytes.length; i++) {
ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
}
return ret.toString();
}
/**
* 功能說明:生成鹽值
* md5 128bit 16bytes
* sha1 160bit 20bytes
* sha256 256bit 32bytes
* sha384 384bit 48bytes
* sha512 512bit 64bytes
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:35:27
* @param saltLength 鹽值長度
* @return 返回生成的鹽值
*/
public static String generateSalt(int saltLength) {
StringBuilder salt = new StringBuilder();
for (int i=0; i<saltLength; i++) {
salt.append(CHAR_ARRAY[random.nextInt(CHAR_ARRAY.length)]);
}
return salt.toString();
}
/**
* 功能說明:爲Sha256加密算法生成32位長度的鹽值
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:36:37
* @return
*/
public static String generateSaltForSha256() {
return generateSalt(32);
}
/**
* 功能說明:爲Sha512加密算法生成64位長度的鹽值
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:37:30
* @return
*/
public static String generateSaltForSha512() {
return generateSalt(64);
}
/**
* 功能說明:比較2個字節數組是否相等
* 修改說明:
* @author zheng
* @date 2020年6月29日 下午2:38:13
* @param a 待比較字節數組
* @param b 待比較字節數組
* @return 相等返回true,否則返回false
*/
public static boolean slowEquals(byte[] a, byte[] b) {
if (a == null || b == null) {
return false;
}
int diff = a.length ^ b.length;
for(int i=0; i<a.length && i<b.length; i++) {
diff |= a[i] ^ b[i];
}
return diff == 0;
}
}
單元測試
HashKtiTest.java
package com.utils;
import org.junit.Test;
public class HashKitTest {
@Test
public void testMd5() {
String srcStr = "zheng";
String result = HashKit.md5(srcStr);
System.out.println("md5 result is " + result);
}
@Test
public void testSha1() {
String srcStr = "zheng";
String result = HashKit.sha1(srcStr);
System.out.println("sha1 result is " + result);
}
@Test
public void testSha256() {
String srcStr = "zheng";
String result = HashKit.sha256(srcStr);
System.out.println("sha256 result is " + result);
}
@Test
public void testSha384() {
String srcStr = "zheng";
String result = HashKit.sha384(srcStr);
System.out.println("sha384 result is " + result);
}
@Test
public void testSha512() {
String srcStr = "zheng";
String result = HashKit.sha512(srcStr);
System.out.println("sha512 result is " + result);
}
}
運行結果
md5 result is 98a8f1a22ffc460364a8a34499118103
sha1 result is 6516f13124863b6872f5f96ea7aa25d8d194e206
sha256 result is 01380046d1d8e2162c4da19af3749b5078881de44f2bf7fc354b12649274bed8
sha384 result is e60732c544571981ee53b2c7bac80d4c9c8316e874c7c9416b5dd3434db8d58b0860f23533f1e563614cfacebd552d86
sha512 result is 76092fabe77d72bea83567773f605b3e014bc63f7b4e04269cee019cb8bacbf725f90b23fbccbe393e1fdae49993c4285cbb0be69711b6475abdef9c60b8caf7