Java消息摘要不';行不通

Java消息摘要不';行不通,java,md5,digest,Java,Md5,Digest,我无法使MessageDigest工作,程序给了我两个错误: 无支持的编码异常,无此算法异常 byte[] bytesOfchat_key = "lol".getBytes("UTF-8"); MessageDigest md = MessageDigest.getInstance("MD5"); byte[] Digest = md.digest(bytesOfchat_key); 如果我抛出错误,它会给我ワ￟ᄡ9ᅦヌnp>0xd￉z作为响应(16个字符) 附言:我曾经打印过这篇摘要

我无法使MessageDigest工作,程序给了我两个错误: 无支持的编码异常,无此算法异常

 byte[] bytesOfchat_key = "lol".getBytes("UTF-8");
 MessageDigest md = MessageDigest.getInstance("MD5");
 byte[] Digest = md.digest(bytesOfchat_key);
如果我抛出错误,它会给我ワ￟ᄡ9ᅦヌnp>0xd￉z作为响应(16个字符)

附言:我曾经打印过这篇摘要

for (byte b : Digest) {
    System.out.print((char)b);
}

md5返回十六进制数,因此要将其解码为字符串,可以使用

String plaintext = "lol";
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());
byte[] digest = m.digest();
//Decoding
BigInteger bigInt = new BigInteger(1,digest);
String hashtext = bigInt.toString(16);
while(hashtext.length() < 32 ){
  hashtext = "0"+hashtext;
}
String plaintext=“lol”;
MessageDigest m=MessageDigest.getInstance(“MD5”);
m、 重置();
m、 更新(明文.getBytes());
字节[]摘要=m.摘要();
//解码
biginger bigInt=新的biginger(1,摘要);
字符串hashtext=bigInt.toString(16);
while(hashtext.length()<32){
hashtext=“0”+hashtext;
}
程序不会给您这些错误-您正在调用可以引发这些异常的方法,因此您需要为这些异常调用catch块,或者声明您的方法也会引发这些异常

摘要的结果是二进制数据,而不是文本。您不应该像这样逐字节将其转换为文本-如果需要将其作为字符串,有两种常见的解决方案:

  • 将每个字节编码为一对十六进制数字
  • 对完整的字节数组使用Base64编码
其中每一项都可以通过以下方式轻松实现


MessageDigest
没有错,但我相信您对异常如何工作以及如何区别对待二进制数据和文本数据的理解有缺陷。

MessageDigest生成的字节不一定代表可打印字符。您应该显示每个字节的数值,或者将字节数组转换为Base64字符串,以便打印

请参阅以获取Base64的实现

您被迫处理的两个异常永远不应该发生,因为任何JVM都保证支持UTF-8,并且JVM本机也支持MD5算法。因此,您应该将代码包装在一个try-catch块中,如下所示:

try {
    byte[] bytesOfchat_key = "lol".getBytes("UTF-8");
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] Digest = md.digest(bytesOfchat_key);
}
catch (NoSuchAlgorithmException e) {
    throw new RuntimeException("something impossible just happened", e);
}
catch (UnsupportedEncodingException e) {
    throw new RuntimeException("something impossible just happened", e);
}
//我遇到一个问题,API中的哈希生成不正确。
//使用eclipse时,它工作正常,但当运行与服务runnable jar相同的API时,会导致生成错误的值。
//这是由java引起的,因为java将小写和大写字母作为不同的Ascii值,而window将它们作为相同的值,所以您只需在字节到十六进制的转换中添加小写和大写字母。
//我希望这对每个人都有帮助。
私有静态字符串makeHash(字符串键到散列){
试一试{
MessageDigest md=MessageDigest.getInstance(“SHA1”);
md.reset();
md.update(key_to_hash.getBytes(Charset.forName(“UTF-8”));
返回bytesToHex(md.digest());
}捕获(例外情况除外){
例如printStackTrace();
}
返回null;
}
私有静态字符串bytesToHex(字节[]b){
字符十六进制数字[]={'0','1','2','3','4','5','6','7','8','9',
‘a’、‘b’、‘c’、‘d’、‘e’、‘f’、‘a’、‘b’、‘c’、‘d’、‘e’、‘f’};
StringBuffer buf=新的StringBuffer();
对于(int j=0;j>4)&0x0f]);
追加(十六进制数字[b[j]&0x0f]);
}
返回buf.toString();
}
// I had the issue that the hash from API was not generating right.
// Using eclipse it was working correctly but when running the same API as the service runnable jar was causing wrong value to produce.

// it was caused by java as Java take Lower case and upper case letters as different Ascii values and window take them as same, so you need to simply add lower and upper case letters in your bytes to hex convertion.
// I hope this helps everyone.
      
 private static String makeHash(String key_to_hash) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA1");
                md.reset();
                md.update(key_to_hash.getBytes(Charset.forName("UTF-8")));
                return bytesToHex(md.digest());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return null;
        }
    
        
    
private static String bytesToHex(byte[] b) {
                char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                        'a', 'b', 'c', 'd', 'e', 'f','A', 'B', 'C', 'D', 'E', 'F' };
                StringBuffer buf = new StringBuffer();
                for (int j = 0; j < b.length; j++) {
                    buf.append(hexDigit[(b[j] >> 4) & 0x0f]);
                    buf.append(hexDigit[b[j] & 0x0f]);
                }
                return buf.toString();
            }