2013-07-09 11 views
16

मुझे प्रदर्शन महत्वपूर्ण वातावरण में MessageDigest का उपयोग करके एकाधिक थ्रेड से कई चाबियाँ हैंश की आवश्यकता है। मुझे पता चला कि MessageDigest थ्रेड सुरक्षित नहीं है क्योंकि यह अपने राज्य को इसके ऑब्जेक्ट में संग्रहीत करता है। कुंजी की थ्रेड सुरक्षित हैशिंग प्राप्त करने का सबसे अच्छा तरीका क्या हो सकता है?जावा में सुरक्षित धागा की आवश्यकता है

उपयोग मामला:

MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); 

//somewhere later, just need to hash a key, nothing else 
messageDigest.update(key); 
byte[] bytes = messageDigest.digest(); 

विशेष रूप से:

  1. विल ThreadLocal कार्य करने की गारंटी? क्या इसका प्रदर्शन दंड होगा?
  2. क्या वस्तुएं अलग-अलग होती हैं और वे एक दूसरे के साथ हस्तक्षेप नहीं करते हैं? प्रलेखन 'नया' ऑब्जेक्ट कहता है, लेकिन मुझे यकीन नहीं है कि यह केवल एक रैपर है (साझा) साझा कंक्रीट क्लास?
  3. यदि getInstance() 'वास्तविक' नई ऑब्जेक्ट्स लौटाता है, क्या हर बार मुझे हैश की गणना करने की आवश्यकता है, तो एक नया उदाहरण बनाने की सलाह दी जाती है? प्रदर्शन जुर्माना के मामले में - कितना महंगा है?

मेरा उपयोग केस बहुत आसान है - बस एक सरल कुंजी हैश है। मैं सिंक्रनाइज़ेशन का उपयोग करने के लिए बर्दाश्त नहीं कर सकता।

धन्यवाद,

उत्तर

27

एक नया MessageDigest उदाहरण हर बार जब आप एक की जरूरत बनाने के लिए।

getInstance() से लौटाए गए सभी उदाहरण अलग-अलग हैं। उन्हें अलग-अलग digests बनाए रखने की जरूरत है, और यदि यह आपके लिए पर्याप्त नहीं है, here's स्रोत के लिए एक लिंक)।

ThreadLocal महंगा-से-निर्माण वस्तुओं को बनाए रखने के लिए थ्रेडपूल के साथ उपयोग किए जाने पर प्रदर्शन लाभ प्रदान कर सकता है। MessageDigest निर्माण के लिए विशेष रूप से महंगा नहीं है (फिर, स्रोत को देखें)।

+1

अगर मैं (codeof getInstance देखें), यह नई वस्तु बनाने के लिए प्रतीत नहीं होता है, बल्कि यह वस्तु पाने के लिए सुरक्षा कॉल वस्तु [] objs = Security.getImpl मैं नीचे परीक्षण का मामला लिखा है: \t संदेश संदेश संदेश Digest1 = MessageDigest.getInstance ("SHA-1"); \t संदेश संदेश संदेश Digest2 = MessageDigest.getInstance ("SHA-1"); // अपडेट और डाइजेस्ट करें और देखा कि संदेश दोनों संदेश अलग हैं, साथ ही उनके आंतरिक ऑब्जेक्ट/बफर भी अलग हैं। तो, मुझे लगता है कि थ्रेडलोकल काम करना चाहिए। और हाँ, यह थ्रेड पूल वाला एक वेब सर्वर है। मैं थ्रेडलोकल का उपयोग करूंगा। धन्यवाद, –

+3

@ एनलपैडिया - मैं ** दृढ़ता से ** ** थ्रेडलोकल 'का उपयोग कर ** ** की सिफारिश नहीं करता हूं। यह समयपूर्व अनुकूलन है। मैंने एक माइक्रो-बेंचमार्क लिखा था जिसमें एक नया 'संदेशडिगस्ट' बनाने के लिए लगभग 2 * माइक्रो * -सेकंड्स लिया गया था। यह पाचन का उपयोग करने वाले कोड द्वारा * दूर * होने जा रहा है। – parsifal

+0

थ्रेडलोकल का उपयोग करने के साथ आप क्या समस्याएं देखते हैं। यहां तक ​​कि यदि मेरे पास सैकड़ों धागे हैं, तो ऐसी सैकड़ों ऐसी वस्तुएं होंगी। मुझे इस तरह की वस्तुओं की स्मृति पदचिह्न वास्तव में कम मिला। ThreadLocal मेरे लिए ठीक काम कर रहा है। मैंने वस्तुओं को बनाने का भी परीक्षण किया और इसमें 4 माइक्रोसॉन्ड ले गए। मैं वास्तव में जानना चाहूंगा कि थ्रेडलोकल –

3

वैकल्पिक रूप से, DigestUtils, संदेशडिगेस्ट के लिए अपाचे कॉमन्स के थ्रेड-सुरक्षित रैपर का उपयोग करें।

sha1() आपको क्या चाहिए करता है:

byte[] bytes = sha1(key)

+0

का उपयोग कर रहा हूं नीचे दिए गए उत्तर को देखें; DigestUtils MessageDigest से अधिक थ्रेडसेफ नहीं है, क्योंकि DigestUtils.getDigest() केवल MessageDigest.getInstance() को कॉल करता है और चेक किए गए अपवाद को एक अनचेक अपवाद में बदल देता है। – Siddhu

+1

यहां बिंदु यह है कि MessageDigest थ्रेड-सुरक्षित नहीं है, इसलिए समवर्ती वातावरण में एक ही उदाहरण का पुन: उपयोग करने से अप्रत्याशित परिणाम होते हैं। एक नया/अलग उदाहरण (उदाहरण के लिए MessageDigest.getInstance पर कॉल करके) हर बार आपकी समस्या हल करता है। DisgestUtils इस अर्थ में थ्रेड-सुरक्षित है कि इसकी प्रत्येक सुविधा विधियां एक नए संदेशडिजिस्ट इंस्टेंस का उपयोग करती हैं, उनमें से प्रत्येक कॉल (कुछ कॉल के बाद) MessageDigest.get एक नया उदाहरण बनाते हैं। उदाहरण के लिए प्रत्येक DigestUtils को कॉल करें। sha256Hex ("मेरी स्ट्रिंग"); MessageDigest – Legna

1

DigestUtils होना प्रतीत नहीं होता है अब और कच्चे MessageDigest से threadsafe। कवर के तहत अभी भी MessageDigest.getInstance का उपयोग करता है।

+1

का एक अलग उदाहरण उपयोग करेगा, यहां बिंदु यह है कि MessageDigest थ्रेड-सुरक्षित नहीं है, इसलिए समवर्ती वातावरण में एक ही उदाहरण का पुन: उपयोग करने से अप्रत्याशित परिणाम होते हैं। एक नया/अलग उदाहरण (उदाहरण के लिए MessageDigest.getInstance पर कॉल करके) हर बार आपकी समस्या हल करता है। DisgestUtils इस अर्थ में थ्रेड-सुरक्षित है कि इसकी प्रत्येक सुविधा विधियां एक नए संदेशडिजिस्ट इंस्टेंस का उपयोग करती हैं, उनमें से प्रत्येक कॉल (कुछ कॉल के बाद) MessageDigest.getInstance एक नया उदाहरण बनाते हैं। उदाहरण के लिए प्रत्येक कॉल DigestUtils पर। sha256Hex ("मेरी स्ट्रिंग"); MessageDigest – Legna

+0

के एक अलग उदाहरण का उपयोग स्पष्टीकरण के लिए धन्यवाद। –

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