Konwertuj ciąg szesnastkowy na int

111

Próbuję przekonwertować ciąg o długości 8 znaków kodu szesnastkowego na liczbę całkowitą, tak żebym mógł wykonać porównanie int zamiast porównywania ciągów w wielu różnych wartościach.

Wiem, że jest to dość trywialne w C ++, ale muszę to zrobić w Javie. Przypadek testowy, który muszę spełnić, polega w zasadzie na przekonwertowaniu „AA0F245C” na int, a następnie z powrotem na ten ciąg, aby wiedzieć, że konwertuje się prawidłowo.

Próbowałem następujących rzeczy:

int decode = Integer.decode("0xAA0F245C");  // NumberFormatException
int decode2 = Integer.decode("AA0F245C"); //NumberFormatException
int parseInt = Integer.parseInt("AA0F245C", 16); //NumberFormatException
int valueOf = Integer.valueOf("AA0F245C", 16); //NumberFormatException

Próbowałem również zrobić to po dwa znaki na raz i pomnożyć wyniki, co oznacza, że ​​konwersja działa, ale liczba jest nieprawidłowa.

int id = 0;
for (int h = 0; h < hex.length(); h= h+2)
{
    String sub = hex.subSequence(h, h+2).toString();

if (id == 0)
    id = Integer.valueOf(sub, 16);
else
    id *= Integer.valueOf(sub, 16);             
 }
//ID = 8445600 which = 80DEA0 if I convert it back. 

Nie mogę korzystać z bibliotek innych firm, abyś wiedział, więc należy to zrobić w standardowych bibliotekach Java.

Z góry dziękuję za pomoc.

Roloc
źródło
Mnożycie się, kiedy powinniście się zmieniać.
Nathan Moinvaziri,
7
0xAA0F245C = 2853119068aleInteger.MAX_VALUE = 0x7fffffff = 2147483647
Pshemo
5
Wiem, że to pytanie trwa od dwóch lat. Jednak java 8 umożliwia inne rozwiązanie. Dodali Integer.parseUnsignedInt("value",radix)metodę, która służy twojemu celowi. Jeśli wartość jest większa, niż Integer.MAX_VALUEjest mapowana na liczbę ujemną.
John

Odpowiedzi:

151

Jest po prostu za duży na int (który ma 4 bajty i jest podpisany).

Posługiwać się

Long.parseLong("AA0F245C", 16);
Denys Séguret
źródło
4
Wspaniale! Dziękuję! Powinienem był to wiedzieć. Ale dzięki temu czuję się lepiej, żadna z 4 osób, o które pytałem przed wysłaniem, też o tym nie wiedziała :). Na marginesie, muszę teraz dowiedzieć się, dlaczego osoba napisała kod, który muszę porównać, do którego mają je jako ints i not longs ... co prawdopodobnie oznacza, że ​​coś innego jest nie tak. Poza tym ... dziękuję za szybką odpowiedź !!!! Przeklinam cię również za okropny komunikat o błędzie ... „Jest za duży” byłby pomocny.
Roloc,
Kiedy próbuję z dużym ciągiem heksadecymalnym, otrzymuję NumberFormatException: For input string: "AF0005E2A6C630059E4754B8799360F5"... Rozwiązanie?
Anum Sheraz
@AnumSheraz nie chcesz konwertować na długą, ale na tablicę bajtów. Zobacz na przykład stackoverflow.com/questions/140131/…
Denys Séguret
Alternatywą dla konwersji na tablicę bajtów dla dużej liczby jest użycie takiej BigIntegerklasy:BigInteger value = new BigInteger(valueString, 16)
Javaru
33

możesz używać w ten sposób

System.out.println(Integer.decode("0x4d2"))    // output 1234
//and vice versa 
System.out.println(Integer.toHexString(1234); //  output is 4d2);
manikant gautam
źródło
1
Podoba mi się ta odpowiedź, nie wiedziałem, że istnieje ogólna metoda niewrażliwa na typ w klasie Integer. dzięki za wiedzę.
Gewure
18

Maksymalna wartość, jaką Integermoże obsłużyć Java, to 2147483657 lub 2 ^ 31-1. Liczba szesnastkowa AA0F245C to 2853119068 jako liczba dziesiętna i jest o wiele za duża, więc musisz użyć

Long.parseLong("AA0F245C", 16);

żeby to działało.

Niekompletne
źródło
off: interesujące, że bardziej szczegółowa odpowiedź, choć 5 minut później, daje tylko 1 głos za w porównaniu do 14. Chociaż to prawda, ten nie powiedział magicznych „4 bajty” i „podpisany” ... hm.
n611x007
9

możesz to łatwo zrobić za pomocą parseInt z parametrem format.

Integer.parseInt("-FF", 16) ; // returns -255

javadoc Integer

ciepło
źródło
link jest uszkodzony
odinthenerd
5

Oto właściwa odpowiedź:

myPassedColor = "#ffff8c85" int colorInt = Color.parseColor(myPassedColor)

HannahCarney
źródło
3

Dla tych z Was, którzy chcą przekonwertować szesnastkową reprezentację podpisanego bajtu z dwuznakowego ciągu na bajt (który w Javie jest zawsze podpisany), jest przykład. Parsowanie ciągu szesnastkowego nigdy nie daje liczby ujemnej, co jest błędne, ponieważ 0xFF wynosi -1 z pewnego punktu widzenia (kodowanie dopełniające do dwóch). Zasada polega na przeanalizowaniu przychodzącego String jako int, który jest większy niż bajt, a następnie zawijaniu liczb ujemnych. Pokazuję tylko bajty, więc ten przykład jest wystarczająco krótki.

String inputTwoCharHex="FE"; //whatever your microcontroller data is

int i=Integer.parseInt(inputTwoCharHex,16);
//negative numbers is i now look like 128...255

// shortly i>=128
if (i>=Integer.parseInt("80",16)){

    //need to wrap-around negative numbers
    //we know that FF is 255 which is -1
    //and FE is 254 which is -2 and so on
    i=-1-Integer.parseInt("FF",16)+i;
    //shortly i=-256+i;
}
byte b=(byte)i;
//b is now surely between -128 and +127

Można to edytować, aby przetwarzać dłuższe liczby. Po prostu dodaj odpowiednio więcej FF lub 00. Aby przeanalizować 8 liczb całkowitych ze znakiem szesnastkowym ze znakiem, należy użyć Long.parseLong, ponieważ FFFF-FFFF, który jest liczbą całkowitą -1, nie pasuje do liczby całkowitej, gdy jest reprezentowana jako liczba dodatnia (daje 4294967295). Potrzebujesz więc Long do przechowywania. Po konwersji na liczbę ujemną i rzutowaniu z powrotem na liczbę całkowitą, będzie pasować. Nie ma 8-znakowego ciągu szesnastkowego, który nie pasowałby na końcu do liczby całkowitej.

JanSmrz
źródło
1

Dodatkową opcją do tych sugerowanych jest użycie BigIntegerklasy. Ponieważ wartości szesnastkowe są często dużymi liczbami, takimi jak wartości sha256 lub sha512, z łatwością przepełnią an inti a long. Podczas gdy konwersja na tablicę bajtów jest opcją, jak pokazują inne odpowiedzi BigInterger, często zapomniana klasa w java jest również opcją.

String sha256 = "65f4b384672c2776116d8d6533c69d4b19d140ddec5c191ea4d2cfad7d025ca2";
BigInteger value = new BigInteger(sha256, 16);
System.out.println("value = " + value);
// 46115947372890196580627454674591875001875183744738980595815219240926424751266
Javaru
źródło
0
//Method for Smaller Number Range:
Integer.parseInt("abc",16);

//Method for Bigger Number Range.
Long.parseLong("abc",16);

//Method for Biggest Number Range.
new BigInteger("abc",16);
Nitish Kumar
źródło
0

Spróbuj z tym:

long abc = convertString2Hex ("1A2A3B");

private  long  convertString2Hex(String numberHexString)
{
    char[] ChaArray = numberHexString.toCharArray();
    long HexSum=0;
    long cChar =0;

    for(int i=0;i<numberHexString.length();i++ )
    {
        if( (ChaArray[i]>='0') && (ChaArray[i]<='9') )
            cChar = ChaArray[i] - '0';
        else
            cChar = ChaArray[i]-'A'+10;
        HexSum = 16 * HexSum + cChar;
    }
    return  HexSum;
}
Josko Marsic
źródło