2011-04-19 13 views
17

मैं हेक्स तार, उनमें से एक का एक समूह है में पार्स और अहस्ताक्षरित हेक्स स्ट्रिंग, उदाहरण के लिए है:जावा - एक हस्ताक्षरित लंबे

d1bc4f7154ac9edb 

जो "-3333702275990511909" के हेक्स मान है। यदि आप Long.toHexString ("d1bc4f7154ac9edb") करते हैं तो यह वही हेक्स है जो आपको मिलता है;

अभी के लिए, मान लें कि मुझे केवल हेक्स स्ट्रिंग मानों तक पहुंच है और यही वह है। ऐसा करने:

Long.parseLong(hexstring, 16); 

काम नहीं करता है क्योंकि यह इसे एक अलग मूल्य में परिवर्तित करता है जो लंबे समय तक बहुत बड़ा होता है। क्या इन हस्ताक्षरित हेक्स मानों को हस्ताक्षरित लम्बाई में परिवर्तित करने के लिए दूर है?

धन्यवाद!

उत्तर

21

आप इसे पार्स और एक long वापस पाने के लिए BigInteger उपयोग कर सकते हैं:

long value = new BigInteger("d1bc4f7154ac9edb", 16).longValue(); 
System.out.println(value); // this outputs -3333702275990511909 
+2

बस आधुनिक दर्शकों के लिए एक नोट: स्कॉट केरी टिप्पणी, जावा 8 से शुरू के रूप में हम बस 'Long.parseUnsignedLong (hexstring, 16) तो शांत कर सकते हैं', :) – NIA

5

आप छमाही में इसे विभाजित कर सकते हैं और एक समय में 32 बिट पढ़ें। फिर 32 से शिफ्ट-बाएं और तार्किक या इसे एक लंबे समय तक वापस लाने के लिए उपयोग करें।

+0

आपको एक कोड नमूना की क्या ज़रूरत है तुम्हारा क्या मतलब है? – Peter

+2

कुछ मोटे तौर पर: (Long.parseLong (hexstring.substring (0, 8), 16) << 32) | (Long.parseLong (hexstring.substring (8, 16), 16) << 0) –

4

नीचे दी गई विधि को हर बार आपको BigInteger ऑब्जेक्ट नहीं बनाने का लाभ होता है।

public class Test { 
    /** 
    * Returns a {@code long} containing the least-significant 64 bits of the unsigned hexadecimal input. 
    * 
    * @param valueInUnsignedHex  a {@link String} containing the value in unsigned hexadecimal notation 
    * @return      a {@code long} containing the least-significant 64 bits of the value 
    * @throws NumberFormatException if the input {@link String} is empty or contains any nonhexadecimal characters 
    */ 
    public static final long fromUnsignedHex(final String valueInUnsignedHex) { 
    long value = 0; 

    final int hexLength = valueInUnsignedHex.length(); 
    if (hexLength == 0) throw new NumberFormatException("For input string: \"\""); 
    for (int i = Math.max(0, hexLength - 16); i < hexLength; i++) { 
     final char ch = valueInUnsignedHex.charAt(i); 

     if  (ch >= '0' && ch <= '9') value = (value << 4) | (ch - '0'  ); 
     else if (ch >= 'A' && ch <= 'F') value = (value << 4) | (ch - ('A' - 0xaL)); 
     else if (ch >= 'a' && ch <= 'f') value = (value << 4) | (ch - ('a' - 0xaL)); 
     else        throw new NumberFormatException("For input string: \"" + valueInUnsignedHex + "\""); 
    } 

    return value; 
    } 

    public static void main(String[] args) { 
    System.out.println(fromUnsignedHex("d1bc4f7154ac9edb")); 
    } 
} 

यह पैदा करता है

-3333702275990511909 
+0

यह अच्छा लग रहा है, लेकिन जैसा आपने ऊपर किया है, अंकों के मान प्राप्त करने के बजाय, शायद Character.digit का उपयोग करना सबसे अच्छा होगा? http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#digit(int,%20int) – asieira

+0

'Character.digit' में सभी यूनिकोड दशमलव अंक शामिल हैं, और मैं नहीं करता उन सभी को संभालना चाहते हैं क्योंकि उनमें से कई सेट हैं, जिनमें से कुछ सही तरीके से प्रलेखित नहीं हैं। – Olathe

+0

मेरा मानना ​​है कि किसी भी संभावित यूनिकोड अंकों के संख्यात्मक मूल्य को निकालने में सक्षम होना आपके कोड को अधिक पोर्टेबल और internatinoalization- अनुकूल बनाकर एक प्लस है। भले ही आपकी प्रोजेक्ट की आवश्यकता न हो, भले ही आपने अपना जवाब अपडेट किया हो तो ओवरफ्लो उपयोगकर्ताओं को स्टैक हो सकता है। बस मेरे 2 सेंट। – asieira

3

पहले जवाब बहुत जटिल या पुराने हो चुके हैं।

Long.parseUnsignedLong(hexstring, 16)