2010-04-15 15 views
12

मैं किसी भी प्रकार की जावा ऑब्जेक्ट के लिए चेकसम उत्पन्न करने के लिए एक समाधान की तलाश में हूं, जो एक ही ऑब्जेक्ट उत्पन्न करने वाले किसी एप्लिकेशन के निष्पादन के लिए समान रहता है।जावा ऑब्जेक्ट के लिए चेकसम उत्पन्न करने के लिए कैसे करें

मैं Object.hashCode() साथ यह कोशिश की, लेकिन एपीआई का कहना है

.... यह पूर्णांक एक ही आवेदन का एक और निष्पादन के लिए एक आवेदन पत्र में से एक निष्पादन से संगत नहीं रहना है।

+0

आप उद्धरण के लिए एक लिंक जोड़ सकते हैं? – Roman

+0

@Roman: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#hashCode%28%29 –

+7

'int checksum (ऑब्जेक्ट ओ) {वापसी 1;} 'आपकी आवश्यकताओं को भरता है :-) –

उत्तर

7

मुझे इसी तरह की समस्या थी (एक्सएमएल फाइलों के लिए अच्छा हैशकोड उत्पन्न करना) और मुझे पता चला कि एमडी 5 MessageDigest के माध्यम से एमडी 5 का उपयोग करने के लिए सबसे अच्छा समाधान है या यदि आपको कुछ तेज चाहिए: Fast MD5। कृपया ध्यान दें कि भले ही Object.hashCode उच्च विशिष्टता सुनिश्चित करने के लिए हर बार यह बहुत छोटा (केवल 32 बिट्स) होगा। मुझे लगता है कि 64 बिट्स अच्छे हैश कोड की गणना करने के लिए न्यूनतम है। कृपया ध्यान रखें कि एमडी 5 128 बिट्स हैश कोड उत्पन्न करता है, जो इस स्थिति में और भी आवश्यक होना चाहिए।

MessageDigest का उपयोग करने के लिए आपको ऑब्जेक्ट पहले (अपने मामले में मार्शल) क्रमबद्ध करने की आवश्यकता है।

+0

आपके उत्तरों के लिए सभी को धन्यवाद। मैं मार्शल अनुरोध से एमडी 5 की गणना करता हूं। – Alex

5

मुझे लगता है कि आपको serialization पर देखना चाहिए। सीरियलाइजेशन तंत्र को इसी तरह की समस्या को हल करने की आवश्यकता है, ताकि आप देख सकें कि यह कैसे कार्यान्वित किया गया है।

लेकिन यदि आप उस समस्या का वर्णन करते हैं जिसे आप हल करने का प्रयास कर रहे हैं तो आपको शायद अधिक सटीक समाधान मिलेगा।

4

यदि आप स्रोत को नियंत्रित करते हैं, तो आप हैशकोड() को कार्यान्वित कर सकते हैं ताकि यह एक निष्पादन से दूसरे में सुसंगत रहे।

3

क्या आप सभी जावा ऑब्जेक्ट्स के लिए ऐसा करने में सक्षम होना चाहते हैं?

उस स्थिति में hashCode() काम नहीं करता है।

कुछ कक्षाओं के लिए hashCode() में एक कठोर परिभाषा है जो निष्पादन में समानता की गारंटी देता है। उदाहरण के लिए String में एक अच्छी तरह से परिभाषित hashCode कार्यान्वयन है। इसी प्रकार List और Set में अच्छी तरह से परिभाषित मान हैं, बशर्ते वे सभी ऑब्जेक्ट्स जिनमें भी हैं, अच्छी तरह से परिभाषित मान हैं (ध्यान दें कि सामान्य Collection.hashCode() मान को अच्छी तरह से परिभाषित करने की आवश्यकता नहीं है)।

अन्य कक्षाओं के लिए आपको चेकसम बनाने के लिए कुछ अच्छी तरह से परिभाषित सूत्र के साथ प्रतिबिंब का उपयोग करना होगा।

2

हैशकोड ठीक है। या तो दिया गया वर्ग equals ओवरराइड करता है और अनुबंध की मांग के अनुसार, hashcode। अनुबंध से, यदि equals रिटर्न true हैशकोड समान होना चाहिए।
या कक्षा equals ओवरराइड नहीं करती है। इस मामले में आपके आवेदन के विभिन्न निष्पादन समान ऑब्जेक्ट का उत्पादन नहीं कर सकते हैं, इसलिए कोई समस्या नहीं है।
एकमात्र समस्या यह है कि कुछ वर्ग (जावा एपीआई से भी) equals के लिए अनुबंध तोड़ते हैं।

2

अपाचे कॉमन्स लैंग लाइब्रेरी HashCodeBuilder कक्षा प्रदान करता है जो एक हैश कोड बनाने में मदद करता है जो कक्षा गुणों से आपकी आवश्यकताओं को भरता है।

उदाहरण:

public int checksum() { 
    // you pick a hard-coded, randomly chosen, non-zero, odd number 
    // ideally different for each class 
    return new HashCodeBuilder(17, 37). 
     append(property1). 
     append(property2). 
     append(property3). 
     toHashCode(); 
    } 

देखें Commons Lang API

2

आप च आप ग्रहण आईडीई का उपयोग कर रहे तो यह क्रिया (स्रोत मेनू के तहत) है कर रहे हैं hashCode पैदा करते हैं और कार्यों के बराबर होती है करने के लिए। यह आपको हैशकोड में इच्छित कक्षा के गुणों को चुनने की अनुमति देता है। यह हैशकोडबिल्डर दृष्टिकोण का उपयोग करने के समान है जिसे पहले से ही सुझाव दिया जा चुका है।

वैकल्पिक रूप से आप ऑब्जेक्ट को बाइट सरणी में स्ट्रीम कर सकते हैं और उसमें से एक MD5 उत्पन्न कर सकते हैं।

8

उदाहरण

 
private BigInteger checksum(Object obj) throws IOException, NoSuchAlgorithmException { 

    if (obj == null) { 
     return BigInteger.ZERO; 
    } 

    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(baos); 
    oos.writeObject(obj); 
    oos.close(); 

    MessageDigest m = MessageDigest.getInstance("SHA1"); 
    m.update(baos.toByteArray()); 

    return new BigInteger(1, m.digest()); 
} 
7
public static String getChecksum(Serializable object) throws IOException, NoSuchAlgorithmException { 
    ByteArrayOutputStream baos = null; 
    ObjectOutputStream oos = null; 
    try { 
     baos = new ByteArrayOutputStream(); 
     oos = new ObjectOutputStream(baos); 
     oos.writeObject(object); 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     byte[] thedigest = md.digest(baos.toByteArray()); 
     return DatatypeConverter.printHexBinary(thedigest); 
    } finally { 
     oos.close(); 
     baos.close(); 
    } 
} 
0
  1. वस्तु -> स्ट्रिंग -

  2. स्ट्रिंग (उदाहरण के लिए, GSON आप क्रमबद्धता अपनी कक्षा के सभी क्षेत्रों को सूचीबद्ध नहीं लिखने के लिए नहीं होगा) .शैशकोड() -> int (ऑब्जेक्ट.hashCode() के बजाय! हैशकोड() का यह अहसास स्ट्रिंग की सामग्री पर निर्भर करता है, स्मृति में पते पर नहीं --- आप इसे विभिन्न ऐप लॉन्च, विभिन्न थ्रेड इत्यादि में उपयोग कर सकते हैं।)

(या 2. स्ट्रिंग -> MD5)

संबंधित मुद्दे