如何用Java编写哈希解码程序还原加密邮箱地址?
Java邮箱哈希解码代码的技术验证与指导
我需要编写Java代码处理哈希编码,实现加密邮箱地址的解码,以下是我写的代码,请帮忙做技术层面的确认或指导:
import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class EmailDecoder { public static void main(String[] args) { String encodedEmail = "f894e71e1551d1833a977df952d0cc9de44a1f9669fbf97d51309a2c6574d5eaa746cd" + "eb9ee1a5dfc771d280d33e5672e48a0b49e999dc7d88f3e7073040596e98687c4d1" + "730f3ac2fb2fe4f3e2fba56af628f412d7fdd02405f755a7a9ed59f2fd71f28ca8fc7500f" + ".....5098b5499d"; String decodedEmail = decodeEmail(encodedEmail); System.out.println(decodedEmail); } public static String decodeEmail(String encodedEmail) { StringBuilder decodedEmail = new StringBuilder(); int length = encodedEmail.length(); for (int i = 0; i < length; i += 64) { String substring = encodedEmail.substring(i, Math.min(i + 64, length)); String reversed = reverseHash(substring); String character = reversed.substring(reversed.length() - 2); decodedEmail.append(character); } return decodedEmail.toString(); } public static String reverseHash(String hash) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = new BigInteger(1, hexToBytes(hash)).toByteArray(); byte[] digest = md.digest(bytes); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } public static byte[] hexToBytes(String hex) { byte[] bytes = new byte[hex.length() / 2]; for (int i = 0; i < bytes.length; i++) { int index = i * 2; int j = Integer.parseInt(hex.substring(index, index + 2), 16); bytes[i] = (byte) j; } return bytes; } }
技术问题分析与改进建议
1. 核心功能缺失:十六进制转字符
当前代码仅将哈希结果的最后两位十六进制字符串拼接,但未将其解析为对应的ASCII字符,最终输出的是十六进制序列而非邮箱地址。需要添加转换步骤:
// 替换decodeEmail方法中的decodedEmail.append(character); char emailChar = (char) Integer.parseInt(character, 16); decodedEmail.append(emailChar);
2. BigInteger转换导致数据失真
reverseHash中通过BigInteger转换字节数组会额外添加0x00前缀(当原字节最高位为1时),导致MD5计算的原始数据与加密时的输入不一致,直接使用hexToBytes的返回值即可:
// 替换reverseHash中的byte[] bytes = new BigInteger(1, hexToBytes(hash)).toByteArray(); byte[] bytes = hexToBytes(hash);
3. 异常处理存在空指针风险
reverseHash捕获异常后返回null,后续调用reversed.substring会触发NullPointerException,建议抛出运行时异常以明确错误:
catch (NoSuchAlgorithmException e) { throw new RuntimeException("MD5算法不可用", e); }
4. 加密规则的强依赖性
当前解码逻辑假设邮箱每个字符对应64位十六进制加密段,且加密规则是对该段原始数据做MD5哈希后取最后两位作为原字符的十六进制。若实际加密规则与此不符,解码逻辑将完全失效,需确保解码逻辑与加密逻辑严格对称。
5. 边界场景处理
当加密字符串长度不是64的整数倍时,需确认剩余片段是否为完整的单个字符加密段,否则会导致末尾字符解码错误。
修正后的完整代码
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class EmailDecoder { public static void main(String[] args) { String encodedEmail = "f894e71e1551d1833a977df952d0cc9de44a1f9669fbf97d51309a2c6574d5eaa746cd" + "eb9ee1a5dfc771d280d33e5672e48a0b49e999dc7d88f3e7073040596e98687c4d1" + "730f3ac2fb2fe4f3e2fba56af628f412d7fdd02405f755a7a9ed59f2fd71f28ca8fc7500f" + ".....5098b5499d"; String decodedEmail = decodeEmail(encodedEmail); System.out.println(decodedEmail); } public static String decodeEmail(String encodedEmail) { StringBuilder decodedEmail = new StringBuilder(); int length = encodedEmail.length(); for (int i = 0; i < length; i += 64) { String substring = encodedEmail.substring(i, Math.min(i + 64, length)); String reversedHash = reverseHash(substring); String charHex = reversedHash.substring(reversedHash.length() - 2); char emailChar = (char) Integer.parseInt(charHex, 16); decodedEmail.append(emailChar); } return decodedEmail.toString(); } public static String reverseHash(String hash) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = hexToBytes(hash); byte[] digest = md.digest(bytes); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("MD5算法不可用", e); } } public static byte[] hexToBytes(String hex) { byte[] bytes = new byte[hex.length() / 2]; for (int i = 0; i < bytes.length; i++) { int index = i * 2; int value = Integer.parseInt(hex.substring(index, index + 2), 16); bytes[i] = (byte) value; } return bytes; } }
内容的提问来源于stack exchange,提问作者berry.11
相关产品推荐
相关产品推荐

