Szesnastkowy do liczby całkowitej w Javie

Próbuję przekonwertować łańcuch szesnastkowy na liczbę całkowitą. Łańcuch szesnastkowy został obliczony z funkcji hash (sha-1). Dostaję ten błąd: java.lang.NumberFormatException. Domyślam się, że nie podoba mu się reprezentacja ciągu szesnastkowego. Jak mogę to osiągnąć? Oto Mój kod:

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();

}

Na przykład, gdy przekazuję ten ciąg znaków : _DTOWsHJbEeC6VuzWPawcLA , jego hash: 0xc934e5d372b2ab6d0a50b9f0341a00ed029bdc15

Ale dostaję : java.lang.NumberFormatException: for input string: " 0xC934E5D372B2AB6D0A50B9F0341A00ed029bdc15 "

Naprawdę muszę to zrobić. Mam zbiór elementów identyfikowanych przez ich UUID, które są ciągiem. Będę musiał przechowywać te elementy, ale moje ograniczenia to użycie liczby całkowitej jako ich id. Dlatego obliczam hash podanego parametru, a następnie konwertuję na int. Może robię to źle, ale czy ktoś może mi doradzić, aby to osiągnąć poprawnie!!

Dzięki za pomoc !!

Author: Dimitri, 2011-05-04

6 answers

Dlaczego nie używasz do tego funkcjonalności Javy:

Jeśli twoje liczby są małe (mniejsze od twoich), możesz użyć: Integer.parseInt(hex, 16) do konwersji ciągu szesnastkowego na liczbę całkowitą.

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

Dla dużych liczb, takich jak twoja, użyj public BigInteger(String val, int radix)

  BigInteger value = new BigInteger(hex, 16);

@Patrz JavaDoc:

 76
Author: Ralph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-03 06:57:44

Możesz użyć tej metody: https://stackoverflow.com/a/31804061/3343174 konwertuje idealnie dowolną liczbę szesnastkową (przedstawioną jako ciąg znaków) na liczbę dziesiętną

 1
Author: Fakher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:52

Spróbuj tego

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
    }
 1
Author: wahid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 10:06:25

SHA-1 generuje 160-bitową wiadomość (20 bajtów), zbyt dużą, aby mogła być przechowywana w wartości int LUB long. Jak sugeruje Ralph, możesz użyć Bigintegera.

Aby uzyskać (mniej bezpieczny) hash int, możesz zwrócić kod hash zwracanej tablicy bajtów.

Alternatywnie, jeśli naprawdę nie potrzebujesz SHA, możesz po prostu użyć uuid ' s String hash code.

 0
Author: Michael Brewer-Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-04 16:30:40

W końcu znajduję odpowiedzi na moje pytanie na podstawie wszystkich twoich komentarzy. Dzięki, próbowałem tego:

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");
    }
    //....
}

To rozwiązanie nie jest optymalne, ale mogę kontynuować mój projekt. Jeszcze raz dziękuję za pomoc

 0
Author: Dimitri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-28 08:46:21

To dlatego, że byte[] output jest dobrze, a tablica bajtów, możesz myśleć o niej jako tablica bajtów reprezentujących każdą z nich liczbę całkowitą, ale gdy dodasz je wszystkie do jednego ciągu, otrzymasz coś, co nie jest liczbą całkowitą, dlatego. Możesz mieć ją jako tablicę liczb całkowitych lub spróbować utworzyć instancję BigInteger .

 -2
Author: OscarRyz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-04 16:35:52