Java:如何保存字符串的原始UTF-8数据?
我正在用Java开发XMPP(Jabber)客户机,我想通过SASL连接到服务器。经过一些研究,我发现这可以解释整个身份验证机制 问题是当我应该将md5散列的结果作为原始数据保存时: 这里有一个技巧-通常当你散列东西时,你会得到一个十六进制值的结果。但是我们不希望这个结果是十六进制值的字符串!我们需要将结果保留为原始数据!如果要对此数据进行十六进制转储,您会发现它是“3a4f5725a748ca945e506e30acd906f0”。但是请记住,我们需要对它的原始数据进行操作,所以不要将其转换为字符串 如何在Java中实现这一点?若我不应该将结果转换为字符串,那个么当我需要在另一个md5哈希中使用它时,我应该如何处理它呢Java:如何保存字符串的原始UTF-8数据?,java,utf-8,xmpp,Java,Utf 8,Xmpp,我正在用Java开发XMPP(Jabber)客户机,我想通过SASL连接到服务器。经过一些研究,我发现这可以解释整个身份验证机制 问题是当我应该将md5散列的结果作为原始数据保存时: 这里有一个技巧-通常当你散列东西时,你会得到一个十六进制值的结果。但是我们不希望这个结果是十六进制值的字符串!我们需要将结果保留为原始数据!如果要对此数据进行十六进制转储,您会发现它是“3a4f5725a748ca945e506e30acd906f0”。但是请记住,我们需要对它的原始数据进行操作,所以不要将其转换为
仅供参考,这是我学校项目的一部分(这不是强制性的,不,我没有通过寻求帮助来作弊)。我这么说是因为我被禁止使用JDK的非标准库(例如com.sun.org.apache)。Java中的
MessageDigest
类可以用来提供MD5哈希程序。从中获得的MD5哈希程序获取一个字节[]
,并返回一个字节[]
。只需保留返回的字节[]
。查看您提供链接的网页,看起来您必须创建其他字节[]
,并将中间结果复制到其他字节[]
的片段中,然后对这些片段进行散列。对不起,我没有真正理解您所说的“原始数据”是什么意思
事实上,如果你有一个字节流或类似的原始数据,不要把它转换成十六进制字符串,只要继续使用那个字节流/数组
我想不建议使用string,因为如果将字节转换为十六进制表示字符串,可能会有使用myHexString.getBytes(“UTF-8”)的诱惑这将不会返回您期望的适当字节数组。如果有人想要为XMPP SASL质询查询计算响应字符串的代码,请参阅:
private static byte[] combineByteArrays(byte[] a, byte[] b) { // combines two byte[] arrays
byte[] result = new byte[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
for (int i = a.length; i < result.length; i++) {
result[i] = b[i-a.length];
}
return result;
}
private static String byteArrayToHex(byte[] array) { // returns hex representation of byte[] array
String resultStr = "";
for (int i=0; i < array.length; i++) {
resultStr += Integer.toString( ( array[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return resultStr;
}
private static String computeResponse(String username, String password, String realm, String nonce, String qop, String cnonce, String digest_uri, String nc) throws NoSuchAlgorithmException { // computes response for challenge query of XMPP server
MessageDigest md5 = MessageDigest.getInstance("MD5");
final byte[] part1 = md5.digest(combineByteArrays(md5.digest((username + ":" + realm + ":" + password).getBytes()), (":" + nonce + ":" + cnonce).getBytes()));
final byte[] part2 = md5.digest(combineByteArrays("AUTHENTICATE:".getBytes(), digest_uri.getBytes()));
final byte[] temp = combineByteArrays(byteArrayToHex(part1).getBytes(), (":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":").getBytes());
final byte[] part3 = md5.digest(combineByteArrays(temp, byteArrayToHex(part2).getBytes()));
return byteArrayToHex(part3);
}
public static void main(String[] args) throws NoSuchAlgorithmException {
/* example data from http://deusty.blogspot.com/2007/09/example-please.html */
String username = "test";
String password = "secret";
String realm = "osXstream.local";
String nonce = "392616736";
String qop = "auth";
String cnonce = "05E0A6E7-0B7B-4430-9549-0FE1C244ABAB";
String digest_uri = "xmpp/osXstream.local";
String nc = "00000001";
/* prints out "37991b870e0f6cc757ec74c47877472b" */
System.out.println(computeResponse(username, password, realm, nonce, qop, cnonce, digest_uri, nc));
}
私有静态字节[]组合字节数组(字节[]a,字节[]b){//组合两个字节[]数组
字节[]结果=新字节[a.length+b.length];
数组复制(a,0,result,0,a.length);
for(int i=a.length;i
我希望能有所帮助。您能添加一些代码吗?类似于“我需要函数X的结果,但格式为Y”的内容。目前还不清楚你到底需要什么样的“原始数据”(字节[])。现在我完全迷路了。我试过:
stringinput=“testing”
MessageDigest md5=MessageDigest.getInstance(“md5”)代码>byte[]result=md5.digest(input.getBytes())如果我把结果打印出来,它就会变成完全的垃圾。如果我试着一个字节一个字节地打印出来,似乎有些字节是负数,这对我来说很奇怪…@MyFlower:是的,这完全是垃圾。这就是散列的工作方式。如果您想查看它,请将其转换为十六进制或base64或其他格式,但要使用它,您将使用字节[]
。我爱您!:-我离正确的解决方案很近,但你给我指出了正确的方向。谢谢大家!@MyFlower:此外,MessageDigest的输出很可能没有有效的UTF-8
Java字符串编码,因此原始UTF-8数据不是正确的单词。