将十六进制字符串转换为整数

135

我正在尝试将一个包含8个字符的十六进制代码字符串转换为整数,以便可以使用整数比较而不是在许多不同值上进行字符串比较。

我知道这在C++中相当简单,但我需要在Java中完成。我需要满足的测试用例基本上是将“AA0F245C”转换为整数,然后再转回该字符串,以便我知道它是否正确转换。

我尝试了以下方法:

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标准库完成。

非常感谢您的帮助。


你应当进行位移运算而非乘法操作。 - Nathan Moinvaziri
7
0xAA0F245C = 2853119068,但 Integer.MAX_VALUE = 0x7fffffff = 2147483647 - Pshemo
7
我知道这个问题已经存在了两年。然而,Java 8 提供了另一个解决方案。他们添加了 Integer.parseUnsignedInt("value",radix) 方法来满足你的需求。如果值大于 Integer.MAX_VALUE,则它将被映射为负数。 - John
9个回答

177

这个数值对于 int 类型来说太大了(int 类型为 4 字节且带符号)。

请使用

Long.parseLong("AA0F245C", 16);

4
太好了,谢谢!我可能本应该知道这个,但是让我感到更好的是,在发布帖子之前询问的4个人也不知道 :). 顺便说一下,现在我得去弄清楚为什么那个写代码的人将我需要比较的整数设置为整型而不是长整型…这可能意味着其他地方出了问题。这不是重点...非常感谢您的快速回答!!!同时Java的错误提示太差了,"它太大了"会很有帮助。 - Roloc
1
当我尝试使用大的十六进制字符串时,我会得到NumberFormatException: For input string: "AF0005E2A6C630059E4754B8799360F5"...解决方案? - Anum Sheraz
@AnumSheraz,您不需要将其转换为长整型,而是要转换为字节数组。例如,请参见https://dev59.com/GXVC5IYBdhLWcg3w7V_3 - Denys Séguret
对于大数,将其转换为字节数组的替代方法是使用 BigInteger 类,如下所示:BigInteger value = new BigInteger(valueString, 16) - Javaru

56

你可以这样使用

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

4
我喜欢这个答案,之前不知道Integer类中有一个通用的、对类型不敏感的方法可以做到这一点。感谢您提供的知识。 - Gewure
同感,我希望我能再点赞5次。 - GhostCat

21

Java中Integer类型可以处理的最大值是2147483657,即2^31-1。 十六进制数AA0F245C转换成十进制数为2853119068,太大了,因此您需要使用

Long.parseLong("AA0F245C", 16);

使其正常工作。


有趣的是,尽管更详细的回答晚了5分钟,但只得到了1个赞,而不是14个。虽然这个回答是正确的,但它没有说神奇的“4字节”和“有符号”... 嗯。 - n611x007

15

您可以使用带有格式参数的parseInt轻松完成此操作。

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

Java文档 Integer


链接已经失效。 - odinthenerd

9

这是正确的答案:

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

解释:上面的代码段展示了如何将一个16进制颜色值字符串转换为整数类型的颜色值。在Android中,可以使用Color.parseColor()方法来完成这个操作。


这显然是指 android.graphics.Color - java.awt.Color 没有 parseColor 方法。问题中没有任何迹象表明可以合理地假设存在 android 库。这个答案不应该有这么多赞。 - rzwitserloot

4
另一种建议是使用BigInteger类。由于十六进制值通常是大数字,例如sha256或sha512的值,它们将很容易地溢出intlong。虽然将其转换为字节数组是其他答案中展示的选项,但在Java中经常被忽视的BigInteger类也是一个选项。
String sha256 = "65f4b384672c2776116d8d6533c69d4b19d140ddec5c191ea4d2cfad7d025ca2";
BigInteger value = new BigInteger(sha256, 16);
System.out.println("value = " + value);
// 46115947372890196580627454674591875001875183744738980595815219240926424751266

3

如果您需要将一个有符号字节的十六进制表示从两个字符的字符串转换为字节(在Java中始终是有符号的),这里有一个示例。解析十六进制字符串永远不会得到负数,这是错误的,因为从某些角度来看0xFF是-1(二进制补码编码)。原则是将传入的字符串解析为int,它比byte大,然后将负数包装起来。我只展示字节,所以示例足够简短。

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)。所以您需要Long来存储它。将其转换为负数并强制转回Integer后,它将适合。最终没有8个字符的十六进制字符串无法适应整数。


1
//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

尝试使用以下代码:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接