Преобразовать шестнадцатеричную строку в int


111

Я пытаюсь преобразовать строку длиной 8 символов шестнадцатеричного кода в целое число, чтобы я мог выполнять сравнение int вместо сравнения строк по множеству разных значений.

Я знаю, что в C ++ это довольно тривиально, но мне нужно сделать это на Java. Тестовый пример, который мне нужно удовлетворить, по сути состоит в том, чтобы преобразовать «AA0F245C» в int, а затем обратно в эту строку, чтобы я знал, что преобразование выполняется правильно.

Я пробовал следующее:

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

Я также пробовал делать это двумя символами за раз и умножать результаты, что преобразование работает, но число неправильное.

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. 

Я не могу использовать сторонние библиотеки, чтобы вы знали, поэтому это нужно делать в стандартных библиотеках Java.

Заранее благодарю за вашу помощь.


Вы умножаетесь, когда должны переходить.
Натан Мойнвазири

7
0xAA0F245C = 2853119068ноInteger.MAX_VALUE = 0x7fffffff = 2147483647
Пшемо

5
Я знаю, что этот вопрос существует уже два года. Однако java 8 допускает другое решение. Они добавили Integer.parseUnsignedInt("value",radix)метод, который служит вашей цели. Если значение больше, чем Integer.MAX_VALUEоно отображается в отрицательное число.
Джон

Ответы:


151

Он просто слишком велик для int (4 байта со знаком).

Использовать

Long.parseLong("AA0F245C", 16);

4
Огромное спасибо! Наверное, я должен был это знать. Но это заставляет меня чувствовать себя лучше, ни один из 4 человек, которых я спросил перед публикацией, тоже не знал об этом :). В качестве примечания, теперь мне нужно выяснить, почему человек написал код, который мне нужно для сравнения целых чисел, чтобы они были целыми, а не длинными ... что, вероятно, означает, что что-то еще не работает. В том-то и дело ... спасибо за быстрый ответ !!!! Также прокляните вас, java, за ваше ужасное сообщение об ошибке ... "Это слишком много" было бы полезно.
Roloc

Когда я пытаюсь использовать большую шестнадцатеричную строку, я получаю NumberFormatException: For input string: "AF0005E2A6C630059E4754B8799360F5"... Решение?
Anum Sheraz

@AnumSheraz вы хотите преобразовывать не в длинный, а в байтовый массив. См., Например, stackoverflow.com/questions/140131/…
Дени Сегурэ,

Альтернативой преобразования в массив байтов для большого числа является использование такого BigIntegerкласса:BigInteger value = new BigInteger(valueString, 16)
Javaru

33

вы можете использовать так

System.out.println(Integer.decode("0x4d2"))    // output 1234
//and vice versa 
System.out.println(Integer.toHexString(1234); //  output is 4d2);

1
Мне нравится этот ответ, я не знал, что для этого есть общий, нечувствительный к типу метод в классе Integer. спасибо за знания.
Gewure

18

Максимальное значение, которое Integerможет обработать Java, - 2147483657 или 2 ^ 31-1. Шестнадцатеричное число AA0F245C - 2853119068 как десятичное число, и оно слишком велико, поэтому вам нужно использовать

Long.parseLong("AA0F245C", 16);

чтобы заставить его работать.


офф: интересно, что более подробный ответ, пусть и через 5 минут, получает только 1 положительный голос по сравнению с 14. Хотя это правда, этот ответ не сказал волшебных «4 байта» и «подписано» ... хм.
n611x007 02



3

Для тех из вас, кому нужно преобразовать шестнадцатеричное представление байта со знаком из двухсимвольной строки в байт (который в Java всегда подписан), есть пример. Анализ шестнадцатеричной строки никогда не дает отрицательного числа, что неверно, потому что 0xFF - это -1 с некоторой точки зрения (кодирование с дополнением до двух). Принцип состоит в том, чтобы проанализировать входящую строку как int, которая больше байта, а затем обернуть отрицательные числа. Я показываю только байты, так что этот пример достаточно короткий.

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

Его можно отредактировать для обработки более длинных номеров. Просто добавьте больше FF или 00 соответственно. Для разбора 8 шестнадцатеричных целых чисел со знаком вам необходимо использовать Long.parseLong, потому что FFFF-FFFF, который является целым числом -1, не вписывается в Integer, когда он представлен как положительное число (дает 4294967295). Значит нужно долго хранить. После преобразования в отрицательное число и возврата к целому, оно подойдет. Не существует восьмизначной шестнадцатеричной строки, которая не помещалась бы в конце целого числа.


1

Дополнительным вариантом к предложенным является использование BigIntegerкласса. Поскольку шестнадцатеричные значения часто представляют собой большие числа, такие как значения sha256 или sha512, они легко переполнят an intи a long. Хотя преобразование в байтовый массив - это вариант, как показывают другие ответы BigInterger, часто забываемый класс в java также является вариантом.

String sha256 = "65f4b384672c2776116d8d6533c69d4b19d140ddec5c191ea4d2cfad7d025ca2";
BigInteger value = new BigInteger(sha256, 16);
System.out.println("value = " + value);
// 46115947372890196580627454674591875001875183744738980595815219240926424751266

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

0

Попробуйте с этим:

длинный 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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.