java - जावा-हैश एल्गोरिदम-सबसे तेज़ कार्यान्वयन




hash md5 sha2 (6)

मैं जानना चाहता हूं कि जावा के लिए हैश एल्गोरिदम का सबसे अच्छा और तेज़ कार्यान्वयन क्या है विशेष रूप से MD5 और SHA-2 512 (SHA512) या 256. मैं चाहता हूं कि कोई फ़ंक्शन एक तर्क के रूप में स्ट्रिंग प्राप्त करे और परिणामस्वरूप हैश को वापस कर दें। धन्यवाद।

संपादित करें: यह प्रत्येक यूआरएल को एक अद्वितीय हैश में मैप करने के लिए है। चूंकि एमडी 5 इस क्षेत्र में विश्वसनीय नहीं है, इसलिए मैं SHA-2 एल्गोरिदम के लिए सर्वोत्तम और तेज़ कार्यान्वयन खोजने में अधिक रुचि रखता हूं। ध्यान दें कि मुझे पता है कि SHA-2 कुछ यूआरएल के लिए एक ही हैश उत्पन्न कर सकता है लेकिन मैं इसके साथ रह सकता हूं।


Answers

विचार करने की एक और बात एमडी 4 का उपयोग कर रही है। यह एमडी 5 के रूप में सुरक्षित नहीं है, लेकिन इसकी गणना भी तेज है। एक्सपी तक विंडोज़ एमडी 4 में पासवर्ड स्टोर और एक्सचेंज करने के लिए इस्तेमाल किया जाता है, इसलिए हम इस हैश का उपयोग करते हैं क्योंकि यह अभी भी हमें इस प्लेटफ़ॉर्म पर प्रमाणीकरण सेवाएं प्रदान करने की अनुमति देता है।


संपादित करें: मैं मूल रूप से प्रश्न को "सबसे तेज़ हैश एल्गोरिदम" के रूप में पढ़ता हूं और इसे "प्रत्येक एल्गोरिदम का सबसे तेज़ कार्यान्वयन" के रूप में स्पष्ट किया गया है। यह एक वैध सवाल है और अन्य ने तेजी से कार्यान्वयन की ओर इशारा किया है। हालांकि जब तक कि आप थोड़े समय में डेटा की बड़ी मात्रा में परेशान नहीं होते हैं, यह बस इतना मायने नहीं रखता है। मुझे संदेह है कि यह मानक जेसीई के साथ प्रदान किए गए कुछ के अलावा कुछ और उपयोग करने के लिए आमतौर पर समय और जटिलता के लायक है।

यूआरएल पतों के लिए आपको कुछ हार्डवेयर की आवश्यकता के लिए आधुनिक हार्डवेयर पर एक लाख प्रति सेकेंड के ऊपर SHA-256 के साथ हैशिंग करना होगा। मैं कल्पना नहीं कर सकता कि अधिकांश अनुप्रयोगों को प्रति हज़ार से अधिक (प्रति दिन 86 मिलियन से अधिक) की आवश्यकता होती है, जिसका मतलब है कि पूरे सीपीयू समय में हैशिंग 1% से कम होगी। तो यहां तक ​​कि यदि आपके पास असीमित तेज़ हैश एल्गोरिदम था, तो आप केवल 1% तक समग्र प्रदर्शन में सुधार करने में सक्षम होंगे।

मूल उत्तर: सर्वश्रेष्ठ और तेज़ दोनों को प्राप्त करना एक दूसरे के साथ बाधाओं में है। बेहतर हैश आमतौर पर धीमे होते हैं। यदि आपको वास्तव में गति की आवश्यकता है और सुरक्षा चिंता का अधिक नहीं है तो MD5 का उपयोग करें। यदि आपको सबसे अच्छी सुरक्षा की आवश्यकता है तो SHA-256 या यहां तक ​​कि SHA-512 के साथ जाएं। आपने इसका उल्लेख नहीं किया है कि आप इसका उपयोग किस प्रकार कर रहे हैं, इसलिए एक या दूसरे की सिफारिश करना मुश्किल है। आप एसएचए -256 के साथ शायद सबसे सुरक्षित जा रहे हैं, क्योंकि यह आधुनिक हार्डवेयर पर किसी भी तरह के अधिकांश मामलों के लिए पर्याप्त तेज़ होना चाहिए। यहां बताया गया है कि आप इसे कैसे कर सकते हैं:

String input = "your string";
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(input.getBytes("UTF-8"));
byte[] hash = digest.digest();

यदि आप इसे सुरक्षा उद्देश्यों के लिए उपयोग कर रहे हैं, जैसे पासवर्ड हैश करना है, तो आपको पाचन में नमक भी जोड़ना चाहिए। यदि आप हैश से प्रिंट करने योग्य स्ट्रिंग चाहते हैं, तो आप इसे हेक्स के रूप में स्ट्रिंग पर वापस एन्कोड कर सकते हैं:

static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();

StringBuilder sb = new StringBuilder(hash.length * 2);
for (byte b : hash) {
    sb.append(HEX_CHARS[(b & 0xF0) >> 4]);
    sb.append(HEX_CHARS[b & 0x0F]);
}
String hex = sb.toString();

एक स्ट्रिंग के लिए, बस hashCode() कॉल करें क्योंकि मेमोरी ओवरहेड में सस्ता है।

अन्यथा मैं निजी हैश के लिए इस कोड की सिफारिश करता हूं:

public static int hash8(String val) throws UnsupportedEncodingException {
    return hash8(val.getBytes("UTF-8"));
}

public static int hash8(byte[] val) {
    int h = 1, i = 0;
    for (; i + 7 < val.length; i += 8) {
        h = 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * 31
                * 31 * 31 * 31 * val[i] + 31 * 31 * 31 * 31 * 31 * 31
                * val[i + 1] + 31 * 31 * 31 * 31 * 31 * val[i + 2] + 31
                * 31 * 31 * 31 * val[i + 3] + 31 * 31 * 31 * val[i + 4]
                + 31 * 31 * val[i + 5] + 31 * val[i + 6] + val[i + 7];
    }
    for (; i + 3 < val.length; i += 4) {
        h = 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * val[i] + 31 * 31
                * val[i + 1] + 31 * val[i + 2] + val[i + 3];
    }
    for (; i < val.length; i++) {
        h = 31 * h + val[i];
    }
    return h;
}

एफवाईआई: http://lemire.me/blog/2015/10/22/faster-hashing-without-effort/



पहली चीजें पहले: गति अतिरंजित है। आपको यह घोषणा करने से पहले उपाय करना चाहिए कि दिया गया एल्गोरिदम "बहुत धीमा" है। अधिकांश समय, हैश फ़ंक्शन की गति वैसे भी कोई ध्यान देने योग्य अंतर नहीं बनाती है। यदि आपके पास सुरक्षा के बारे में योग्यता है, तो पहले एक हैश फ़ंक्शन का चयन करें जो पर्याप्त सुरक्षित है, और उसके बाद केवल प्रदर्शन के बारे में चिंता करें।

इसके अलावा, आप हैश "तार" करना चाहते हैं। एक जावा String , आंतरिक रूप से, char मानों की एक सरणी से एक खंड है जो यूनिकोड कोड बिंदुओं का प्रतिनिधित्व करता है (वास्तव में, यूनिकोड 16-बिट कोड इकाइयां जो यूटीएफ -16 का उपयोग करके कोड बिंदु को एन्कोड करते हैं)। एक हैश फ़ंक्शन बिट्स या बाइट्स का अनुक्रम इनपुट के रूप में लेता है। तो आपको बाइट्स के गुच्छा के रूप में अपनी स्ट्रिंग प्राप्त करने के लिए, एक रूपांतरण चरण बनाना होगा, उदाहरण के लिए str.getBytes("UTF-8") । ऐसा लगता है कि हैशिंग की तुलना में रूपांतरण चरण में एक गैर-नगण्य लागत होगी।

नोट: यूआरएल-एन्कोडिंग से सावधान रहें! एक यूआरएल में, कुछ बाइट्स को ' % ' चिह्न से शुरू होने वाले अनुक्रमों के साथ प्रतिस्थापित किया जा सकता है; यह गैर-प्रिंट करने योग्य पात्रों का समर्थन करने के लिए है, लेकिन इसका उपयोग "मानक" वर्णों पर भी किया जा सकता है (उदाहरण के लिए, ' a ' को ' %61 ' से बदलना)। इसका मतलब है कि दो तार जो अलग हैं (स्ट्रिंग. String.equals() अर्थ में) वास्तव में एक ही यूआरएल का प्रतिनिधित्व कर सकते हैं (जहां तक ​​यूआरएल प्रसंस्करण का संबंध है)। आपकी स्थिति के आधार पर, यह एक मुद्दा हो सकता है या नहीं भी हो सकता है।

आपको पहले जावा ( MessageDigest पहले से स्थापित) जेसीई प्रदाता (यानी आप MessageDigest.getInstance("SHA-256") ) कहते हैं, के साथ जावा के MessageDigest एपीआई का उपयोग करने का प्रयास करना चाहिए, और परिणाम को बेंच करना चाहिए। सैद्धांतिक रूप से, जेसीई "देशी" कोड (सी या असेंबली में लिखे गए) के साथ कार्यान्वयन के लिए कॉल को मैप कर सकता है, जो जावा के साथ आप जो भी प्राप्त कर सकते हैं उससे तेज़ होगा।

ऐसा कहे जाने के बाद...

sphlib सी और जावा में कई क्रिप्टोग्राफिक हैश फ़ंक्शंस का एक ओपनसोर्स कार्यान्वयन है। कोड को गति के लिए अनुकूलित किया गया है, और, व्यावहारिक रूप से, जावा संस्करण सूर्य / ओरेकल ऑफ़र से मानक जेआरई की तुलना में तेज़ हो जाता है। पिछला लिंक विफल होने पर इस लिंक का उपयोग करें (मुख्य मेजबान सर्वर कभी-कभी रखरखाव के लिए नीचे होता है, जैसा कि अभी मामला लगता है) (चेतावनी: 10 एमबी डाउनलोड)। संग्रह में एक रिपोर्ट भी शामिल है (जिसे 2010 में दूसरे एसएचए -3 उम्मीदवार सम्मेलन में प्रस्तुत किया गया था) जो एसएचए -2 के लिए कई प्लेटफार्मों पर कुछ मापा प्रदर्शन आंकड़े और आगामी SHA-3 के लिए 14 "दूसरे दौर" उम्मीदवारों को देता है।

लेकिन आपको वास्तव में स्थिति में बेंचमार्क बनाना चाहिए। उदाहरण के लिए, एल 1 कैश पर प्रभाव प्रदर्शन पर एक कठोर प्रभाव डाल सकते हैं, और फ़ंक्शन कोड लेने और इसे अलगाव में चलाकर सटीक रूप से पूर्वानुमानित नहीं किया जा सकता है।


यह पृष्ठ संरक्षित और डिफ़ॉल्ट पहुंच संशोधक के बारे में अच्छी तरह से लिखता है

.... संरक्षित: संरक्षित एक्सेस संशोधक थोड़ा मुश्किल है और आप डिफ़ॉल्ट पहुंच संशोधक का सुपरसैट कह सकते हैं। संरक्षित सदस्य डिफ़ॉल्ट सदस्यों के समान हैं जहां तक ​​एक ही पैकेज में पहुंच का संबंध है। अंतर यह है कि, संरक्षित सदस्य कक्षा के उप-वर्गों के लिए भी पहुंच योग्य होते हैं जिसमें सदस्य घोषित किया जाता है जो कि पैकेज के बाहर होते हैं जिसमें मूल वर्ग मौजूद होता है।

लेकिन ये संरक्षित सदस्य "केवल विरासत के माध्यम से पैकेज के बाहर सुलभ" हैं। यानी आप अपने उप-वर्ग में किसी वर्ग के संरक्षित सदस्य को किसी अन्य पैकेज में सीधे एक्सेस कर सकते हैं जैसे कि सदस्य उप-वर्ग में मौजूद है। लेकिन वह संरक्षित सदस्य मूल वर्ग के संदर्भ का उपयोग करके पैकेज के बाहर उप-वर्ग में पहुंच योग्य नहीं होगा। ....





java hash md5 sha2