Java实现的方式 32位十六进制字符串的形式返回 返回大写字母的字符串
// 定义一个静态数组,存储十六进制的数字字符
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" };
/**
* 计算字符串的MD5值,使用UTF-8编码
* @param input 输入字符串
* @return MD5值的十六进制字符串
*/
public static String md5(String input) {
// 调用MD5Encode方法进行MD5加密,使用UTF-8编码
return MD5Encode(input, "UTF-8");
}
/**
* 核心MD5计算方法,返回字节数组形式的MD5值
* @param data 待加密的数据
* @param encodingType 编码类型
* @return MD5值的字节数组
*/
public synchronized static final byte[] toMd5(String data, String encodingType) {
// 初始化MessageDigest对象
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException nsae) {
System.err.println("Failed to load the MD5 MessageDigest.");
nsae.printStackTrace();
}
// 如果数据为空或只含空格,则返回null
if (StringUtils.isBlank(data)) {
return null;
}
try {
// 使用指定的编码类型更新摘要
digest.update(data.getBytes(encodingType));
} catch (UnsupportedEncodingException e) {
// 如果编码类型不支持,则使用默认编码
digest.update(data.getBytes());
}
// 返回MD5摘要的字节数组
return digest.digest();
}
/**
* 将字节数组转换为十六进制字符串
* @param origin 原始数据
* @param encodingType 编码类型
* @return MD5值的十六进制字符串
*/
public static String MD5Encode(String origin, String encodingType) {
// 获取MD5字节数组
byte[] md5Bytes = toMd5(origin, encodingType);
// 将字节数组转换为十六进制字符串
return byteArrayToHexString(md5Bytes);
}
/**
* 将字节数组转换为十六进制字符串
* @param b 字节数组
* @return 十六进制字符串
*/
public static String byteArrayToHexString(byte[] b) {
// 使用StringBuffer来构建十六进制字符串
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
// 将每个字节转换为十六进制字符串,并添加到resultSb中
resultSb.append(byteToHexString(b[i]));
}
// 返回最终的十六进制字符串
return resultSb.toString();
}
/**
* 将单个字节转换为两位的十六进制字符
* @param b 字节
* @return 十六进制字符串
*/
private static String byteToHexString(byte b) {
// 确保字节值是非负的
int n = b;
if (n < 0) n = 256 + n;
// 计算十六进制的高位和低位
int d1 = n / 16;
int d2 = n % 16;
// 返回对应的十六进制字符
return hexDigits[d1] + hexDigits[d2];
}
将 MD5散列值的十六进制字符串
下面是每个方法的详细解释,用中文进行说明:
1. hexDigits
数组
这个数组包含了十六进制数字的字符表示,用于后续将字节转换为十六进制字符串。
2. md5(String input)
这是一个公有的静态方法,接受一个字符串参数input
,并返回其MD5散列值。它调用了MD5Encode
方法来执行实际的转换,并使用了"UTF-8"编码。
3. toMd5(String data, String encodingType)
此方法实现了MD5算法的核心部分。首先,它获取MessageDigest
实例,用于执行MD5哈希计算。如果输入数据为空或只包含空白字符,则返回null
。然后,它尝试使用指定的encodingType
对数据进行编码,但如果编码类型不支持,则默认使用平台默认的字符编码。最后,它返回计算出的MD5哈希值(以字节数组形式)。
4. MD5Encode(String origin, String encodingType)
这个方法将原始字符串转换为其MD5散列值的十六进制字符串表示。它先通过toMd5
方法获得MD5字节数组,然后调用byteArrayToHexString
将其转换为十六进制字符串。
5. byteArrayToHexString(byte[] b)
该方法接收一个字节数组,并返回一个十六进制字符串。它遍历数组中的每个字节,使用byteToHexString
方法将每个字节转换为两位的十六进制字符,并将结果拼接到StringBuffer
中。
6. byteToHexString(byte b)
这是一个私有辅助方法,用于将单个字节转换为其十六进制表示。它首先将字节转换为整数,确保它是非负的(因为字节是带符号的)。然后,它通过除法和取模运算确定两个十六进制位的值,并从hexDigits
数组中选择相应的字符。
总之,这些方法共同工作,将输入字符串转换为其MD5散列值的十六进制字符串表示。
文本的MD5散列值,以32位十六进制字符串的形式返回。 返回小写字母的字符串
/**
* 生成给定文本的MD5散列值。
*
* @param txt 需要进行MD5散列的文本。
* @return 文本的MD5散列值,以32位十六进制字符串的形式返回。
* @throws RuntimeException 如果MD5算法不可用时抛出运行时异常。
*/
public static String md5(String txt) {
try {
// 创建MD5算法的MessageDigest实例
MessageDigest md = MessageDigest.getInstance("MD5");
// 对输入文本进行字节编码,使用UTF-8字符集
byte[] messageDigest = md.digest(txt.trim().getBytes(StandardCharsets.UTF_8));
// 将字节数组转换为BigInteger,以便于转换成十六进制表示
BigInteger no = new BigInteger(1, messageDigest);
// 创建StringBuilder用于构建十六进制字符串
StringBuilder hashtext = new StringBuilder(no.toString(16));
// 确保散列文本长度为32位,不足则在前面填充0
while (hashtext.length() < 32) {
hashtext.insert(0, "0");
}
// 返回最终的MD5散列值
return hashtext.toString();
} catch (NoSuchAlgorithmException e) {
// 抛出运行时异常,指示MD5算法未找到
throw new RuntimeException("MD5 algorithm not found", e);
}
}
第一个方法 :使用自定义的byteToHexString
和byteArrayToHexString
方法,逐字节转换并拼接成十六进制字符串,通过hexDigits
数组实现
第二个方法 :使用BigInteger
的构造函数和toString(16)
方法来转换字节数组为十六进制字符串,然后确保字符串长度为32位。
建议使用第二个方法(与.net 生成加密串相同)