35

I am trying to convert a String hexadecimal to an integer. The string hexadecimal was calculated from a hash function (sha-1). I get this error : java.lang.NumberFormatException. I guess it doesn't like the String representation of the hexadecimal. How can I achieve that. Here is my code :

public Integer calculateHash(String uuid) {

    try {
        MessageDigest digest = MessageDigest.getInstance("SHA1");
        digest.update(uuid.getBytes());
        byte[] output = digest.digest();

        String hex = hexToString(output);
        Integer i = Integer.parseInt(hex,16);
        return i;           

    } catch (NoSuchAlgorithmException e) {
        System.out.println("SHA1 not implemented in this system");
    }

    return null;
}   

private String hexToString(byte[] output) {
    char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'A', 'B', 'C', 'D', 'E', 'F' };
    StringBuffer buf = new StringBuffer();
    for (int j = 0; j < output.length; j++) {
        buf.append(hexDigit[(output[j] >> 4) & 0x0f]);
        buf.append(hexDigit[output[j] & 0x0f]);
    }
    return buf.toString();

}

For example, when I pass this string : _DTOWsHJbEeC6VuzWPawcLA, his hash his : 0xC934E5D372B2AB6D0A50B9F0341A00ED029BDC15

But i get : java.lang.NumberFormatException: For input string: "0xC934E5D372B2AB6D0A50B9F0341A00ED029BDC15"

I really need to do this. I have a collection of elements identified by their UUID which are string. I will have to store those elements but my restrictions is to use an integer as their id. It is why I calculate the hash of the parameter given and then I convert to an int. Maybe I am doing this wrong but can someone gives me an advice to achieve that correctly!!

Thanks for your help !!

Dimitri
  • 8,122
  • 19
  • 71
  • 128
  • 2
    first of all number is too big for regular integer. – Andrey May 04 '11 at 16:28
  • 1
    As Andrey says, it won't fit in a regular integer. If you're happy to change to java.math.BigInteger, you can just `return new BigInteger(1, digest.digest())`. – eggyal May 04 '11 at 16:33

6 Answers6

102

Why do you not use the java functionality for that:

If your numbers are small (smaller than yours) you could use: Integer.parseInt(hex, 16) to convert a Hex - String into an integer.

  String hex = "ff"
  int value = Integer.parseInt(hex, 16);  

For big numbers like yours, use public BigInteger(String val, int radix)

  BigInteger value = new BigInteger(hex, 16);

@See JavaDoc:

Ralph
  • 118,862
  • 56
  • 287
  • 383
  • 1
    I really don't get this answer, isn't that what he's already trying in `Integer i = Integer.parseInt(hex,16);`? – OscarRyz May 04 '11 at 16:32
  • Additionally get rid of the `0x` part... I don't know that this is allowed.. and if you can guarantee that it will always be `0xABC982..`, then you can always just remove the first 2 chars – Java Drinker May 04 '11 at 16:41
  • 1
    I think you mean to instantiate a new BigInteger in your third line of code? It also ought to be more efficient to construct directly from the byte array rather than the hexadecimal string representation. – eggyal May 04 '11 at 16:42
  • @eggyal: You are right, it is new BigInteger - I have corrected it – Ralph Aug 03 '11 at 06:58
3

Try this

public static long Hextonumber(String hexval)
    {
        hexval="0x"+hexval;
//      String decimal="0x00000bb9";
        Long number = Long.decode(hexval);
//.......       System.out.println("String [" + hexval + "] = " + number);
        return number;
        //3001
    }
wahid
  • 41
  • 3
0

you can use this method : https://stackoverflow.com/a/31804061/3343174 it's converting perfectly any hexadecimal number (presented as a string) to a decimal number

Community
  • 1
  • 1
Fakher
  • 2,098
  • 3
  • 29
  • 45
0

SHA-1 produces a 160-bit message (20 bytes), too large to be stored in an int or long value. As Ralph suggests, you could use BigInteger.

To get a (less-secure) int hash, you could return the hash code of the returned byte array.

Alternatively, if you don't really need SHA at all, you could just use the UUID's String hash code.

Michael Brewer-Davis
  • 14,018
  • 5
  • 37
  • 49
  • I tried to use the UUID's String hash code but I get also IllegalArgumentException. This is why I drop UUID; By the way, I don't even know how they generate their UUID, it is not my project – Dimitri May 04 '11 at 16:35
  • By "UUID's String hash code" I mean `uuid.hashCode()` (which uses the function `String.hashCode()`). I can't see that giving an IAE? – Michael Brewer-Davis May 04 '11 at 16:41
  • Yeah, i know. I just tried this method. But the problem is when I try String id = UUID.fromString(uuid) i get an IllegalArgumentException. – Dimitri May 04 '11 at 16:44
0

I finally find answers to my question based on all of your comments. Thanks, I tried this :

public Integer calculateHash(String uuid) {

    try {
        //....
        String hex = hexToString(output);
        //Integer i = Integer.valueOf(hex, 16).intValue();
        //Instead of using Integer, I used BigInteger and I returned the int value.
        BigInteger bi = new BigInteger(hex, 16);
        return bi.intValue();`
    } catch (NoSuchAlgorithmException e) {
        System.out.println("SHA1 not implemented in this system");
    }
    //....
}

This solution is not optimal but I can continue with my project. Thanks again for your help

Ashish Aggarwal
  • 3,018
  • 2
  • 23
  • 46
Dimitri
  • 8,122
  • 19
  • 71
  • 128
-2

That's because the byte[] output is well, and array of bytes, you may think on it as an array of bytes representing each one an integer, but when you add them all into a single string you get something that is NOT an integer, that's why. You may either have it as an array of integers or try to create an instance of BigInteger.

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • Is it possible to convert from BigInteger to Integer? – Dimitri May 04 '11 at 16:40
  • Only if the value of BigInteger is not larger than Integer.MAX_VALUE which in this case it will be. See: http://download.oracle.com/javase/6/docs/api/java/math/BigInteger.html#intValue() – OscarRyz May 04 '11 at 16:56
  • 2
    This answer is basically meaningless. An array of bytes is simply a multiple-precision number. Doesn't answer the question. – user207421 May 05 '11 at 00:23