แปลงสตริงฐานสิบหกเป็น 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

ขอบคุณสำหรับความช่วยเหลือล่วงหน้า


คุณกำลังทวีคูณเมื่อคุณควรจะขยับ
Nathan Moinvaziri

7
0xAA0F245C = 2853119068แต่Integer.MAX_VALUE = 0x7fffffff = 2147483647
Pshemo

5
ฉันรู้ว่าคำถามนี้มีมาประมาณสองปีแล้ว อย่างไรก็ตาม java 8 เปิดใช้งานโซลูชันอื่น พวกเขาเพิ่มInteger.parseUnsignedInt("value",radix)วิธีการที่ตอบสนองวัตถุประสงค์ของคุณ หากค่ามากกว่าInteger.MAX_VALUEจะแมปกับจำนวนลบ
John

คำตอบ:


151

มันใหญ่เกินไปสำหรับ int (ซึ่งมีขนาด 4 ไบต์และเซ็นชื่อ)

ใช้

Long.parseLong("AA0F245C", 16);

4
สุดยอดขอบคุณ! ฉันควรจะรู้ว่า แต่มันทำให้ฉันรู้สึกดีขึ้นไม่มีคน 4 คนที่ฉันถามก่อนโพสต์ก็รู้เช่นกัน :) ตามหมายเหตุด้านข้างตอนนี้ฉันต้องค้นหาว่าทำไมคน ๆ นั้นถึงเขียนโค้ดที่ฉันต้องเปรียบเทียบ ints เพื่อให้พวกเขาเป็น ints และไม่นาน ... ซึ่งอาจหมายความว่าอย่างอื่นปิดอยู่ นั่นคือประเด็น ... ขอบคุณสำหรับคำตอบด่วน !!!! นอกจากนี้ยังด่าคุณ java สำหรับข้อความแสดงข้อผิดพลาดที่น่ากลัวของคุณ ... "มันใหญ่" จะเป็นประโยชน์
Roloc

เมื่อลองใช้สาย hex ขนาดใหญ่ฉันจะได้รับNumberFormatException: For input string: "AF0005E2A6C630059E4754B8799360F5"... วิธีแก้ไข?
Anum Sheraz

@AnumSheraz คุณไม่ต้องการแปลงเป็นอาร์เรย์แบบยาว แต่เป็นไบต์ ดูตัวอย่างstackoverflow.com/questions/140131/…
Denys Séguret

อีกทางเลือกหนึ่งในการแปลงเป็นอาร์เรย์ไบต์สำหรับจำนวนมากคือการใช้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

ค่าสูงสุดที่ Java Integerสามารถจัดการได้คือ 2147483657 หรือ 2 ^ 31-1 เลขฐานสิบหก AA0F245C คือ 2853119068 เป็นเลขฐานสิบและมีขนาดใหญ่เกินไปดังนั้นคุณต้องใช้

Long.parseLong("AA0F245C", 16);

เพื่อให้มันใช้งานได้


ปิด: น่าสนใจที่คำตอบที่ละเอียดกว่าแม้ว่า 5 นาทีต่อมาจะได้รับการโหวตเพียง 1 ครั้งเมื่อเทียบกับ 14 แม้ว่าจะเป็นความจริง แต่คำตอบนี้ไม่ได้ระบุว่ามีมนต์ขลัง '4 ไบต์' และ 'ลงชื่อ' ... hm
n611x007



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 จะไม่พอดีกับจำนวนเต็มเมื่อแสดงเป็นจำนวนบวก (ให้ 4294967295) ดังนั้นคุณต้องใช้เวลานานในการจัดเก็บ หลังจากแปลงเป็นจำนวนลบและส่งกลับเป็นจำนวนเต็มก็จะพอดี ไม่มีสตริงเลขฐานสิบหกอักขระ 8 ตัวซึ่งจะไม่พอดีกับจำนวนเต็มในตอนท้าย


1

ตัวเลือกเพิ่มเติมสำหรับสิ่งที่แนะนำคือการใช้BigIntegerคลาส ตั้งแต่ค่าฐานสิบหกเป็นตัวเลขขนาดใหญ่มักจะเช่น SHA256 หรือ SHA512 ค่าที่พวกเขาจะได้อย่างง่ายดายล้นและint 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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.