Created
September 28, 2014 00:36
-
-
Save stuntguy3000/32c5f6e7d2912cf16b60 to your computer and use it in GitHub Desktop.
how to generate minecraft hex digests in java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.serverid; | |
import java.io.UnsupportedEncodingException; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
public class ServerID | |
{ | |
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); | |
public static void main(String[] args) | |
{ | |
// The test values provided on http://wiki.vg/Protocol_Encryption are: | |
// sha1(Notch) : 4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48 | |
// sha1(jeb_) : -7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1 | |
System.out.println(javaHexDigest("Notch")); | |
System.out.println(javaHexDigest("jeb_")); | |
} | |
private static String javaHexDigest(String data) | |
{ | |
MessageDigest digest = null; | |
try { | |
digest = MessageDigest.getInstance("SHA-1"); | |
digest.reset(); | |
digest.update(data.getBytes("UTF-8")); | |
} catch (NoSuchAlgorithmException e) { | |
e.printStackTrace(); | |
} catch (UnsupportedEncodingException e) { | |
e.printStackTrace(); | |
} | |
byte[] hash = digest.digest(); | |
boolean negative = (hash[0] & 0x80) == 0x80; | |
if (negative) | |
hash = twosCompliment(hash); | |
String digests = getHexString(hash); | |
if (digests.startsWith("0")) | |
{ | |
digests = digests.replaceFirst("0", digests); | |
} | |
if (negative) | |
{ | |
digests = "-" + digests; | |
} | |
digests = digests.toLowerCase(); | |
return digests; | |
} | |
public static String getHexString(byte[] bytes) { | |
char[] hexChars = new char[bytes.length * 2]; | |
int v; | |
for ( int j = 0; j < bytes.length; j++ ) { | |
v = bytes[j] & 0xFF; | |
hexChars[j * 2] = hexArray[v >>> 4]; | |
hexChars[j * 2 + 1] = hexArray[v & 0x0F]; | |
} | |
return new String(hexChars); | |
} | |
private static byte[] twosCompliment(byte[] p) | |
{ | |
int i; | |
boolean carry = true; | |
for (i = p.length - 1; i >= 0; i--) | |
{ | |
p[i] = (byte)~p[i]; | |
if (carry) | |
{ | |
carry = p[i] == 0xFF; | |
p[i]++; | |
} | |
} | |
return p; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code is broken.
This code will not generate correct hashes in a lot of cases. I wrote a small test suite to generate 2000 random strings, and compare the hashed value to the one generated by vanilla (effectively
new BigInteger(md.digest()).toString(16)
). I found it has a 13% failure rate, and here are some examples of the way this fails:Final output from the test suite:
Done. 273/2000 failed (13% failure rate)
In short, DO NOT USE THIS CODE. It will silently fail in subtle ways, which will result in server authentication failing for seemingly no reason... 13% of the time.