हैश मान बनाने के लिए एक्सेल फ़ंक्शन है?


26

मैं कई डेटा सूचियों के साथ काम कर रहा हूं, जो दस्तावेज़ नाम से कुंजीबद्ध हैं। दस्तावेज़ के नाम, जबकि बहुत ही वर्णनात्मक, काफी बोझिल हैं अगर मुझे उन्हें देखने की ज़रूरत है (256 बाइट्स अचल संपत्ति का एक बहुत कुछ है) और मैं एक छोटे से कुंजी क्षेत्र को बनाने में सक्षम होना पसंद करूंगा जो मामले में आसानी से प्रतिलिपि प्रस्तुत करने योग्य है। VLOOKUPकिसी अन्य कार्यपत्रक या कार्यपुस्तिका से करने के लिए ।

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

इस या किसी अन्य रणनीति पर कोई विचार या विचार?

जवाबों:


34

आपको अपना कार्य लिखने की आवश्यकता नहीं है - दूसरों ने पहले से ही आपके लिए किया है।
उदाहरण के लिए मैंने इस स्टैकओवरफ्लो उत्तर पर पांच VBA हैश फ़ंक्शंस एकत्र किए और उनकी तुलना की

व्यक्तिगत रूप से मैं इस VBA फ़ंक्शन का उपयोग करता हूं

  • =BASE64SHA1(A1)आपके द्वारा VBA मॉड्यूल में मैक्रो की प्रतिलिपि बनाने के बाद इसकी एक्सेल के साथ कॉल की जाती है
  • इसके लिए .NET की आवश्यकता है क्योंकि यह लाइब्रेरी "Microsoft MSXML" (देर से बाध्यकारी के साथ) का उपयोग करता है

Public Function BASE64SHA1(ByVal sTextToHash As String)

    Dim asc As Object
    Dim enc As Object
    Dim TextToHash() As Byte
    Dim SharedSecretKey() As Byte
    Dim bytes() As Byte
    Const cutoff As Integer = 5

    Set asc = CreateObject("System.Text.UTF8Encoding")
    Set enc = CreateObject("System.Security.Cryptography.HMACSHA1")

    TextToHash = asc.GetBytes_4(sTextToHash)
    SharedSecretKey = asc.GetBytes_4(sTextToHash)
    enc.Key = SharedSecretKey

    bytes = enc.ComputeHash_2((TextToHash))
    BASE64SHA1 = EncodeBase64(bytes)
    BASE64SHA1 = Left(BASE64SHA1, cutoff)

    Set asc = Nothing
    Set enc = Nothing

End Function

Private Function EncodeBase64(ByRef arrData() As Byte) As String

    Dim objXML As Object
    Dim objNode As Object

    Set objXML = CreateObject("MSXML2.DOMDocument")
    Set objNode = objXML.createElement("b64")

    objNode.DataType = "bin.base64"
    objNode.nodeTypedValue = arrData
    EncodeBase64 = objNode.text

    Set objNode = Nothing
    Set objXML = Nothing

End Function

हैश लंबाई को अनुकूलित करना

  • हैश शुरू में एक 28 अक्षर लंबा यूनिकोड स्ट्रिंग (केस संवेदी + विशेष वर्ण) है
  • आप इस पंक्ति के साथ हैश की लंबाई को अनुकूलित करते हैं: Const cutoff As Integer = 5
  • 4 अंक हैश = 6895 लाइनों में 36 टकराव = 0.5% टक्कर दर
  • 5 अंक हैश = 0 टक्कर 6895 लाइनों में = 0% टक्कर दर

हैश फ़ंक्शंस ( सभी तीन CRC16 फ़ंक्शन ) भी हैं, जिन्हें .NET की आवश्यकता नहीं है और बाहरी पुस्तकालयों का उपयोग नहीं करता है। लेकिन हैश लंबा है और अधिक टकराव पैदा करता है।

आप केवल इस उदाहरण कार्यपुस्तिका को डाउनलोड कर सकते हैं और सभी 5 हैश कार्यान्वयनों के साथ खेल सकते हैं। जैसा कि आप देख रहे हैं कि पहली शीट पर एक अच्छी तुलना है


1
अच्छा लग रहा है। हालाँकि, एक्सेल को वापस जाने से रोकने के लिए मेरे पास पर्याप्त VBA अनुभव नहीं है #NAME?। नई विंडो में कोड> कट और पेस्ट कोड देखें - नेविगेटर में सही वर्कशीट के भीतर> मैक्रो-सक्षम वर्कशीट के रूप में सहेजें> पास और एक्सेल में वापस ... कुछ और जो मैं याद कर रहा हूं? क्या मुझे इसे किसी तरह संकलित करने की आवश्यकता है?
dwwilson66 16

हां ... स्पष्ट करने के लिए ... मैंने इसे नए कोड विंडो में चिपकाया, जो उस समय पॉप अप हुआ जब मैं वर्कशीट टैब> व्यू कोड पर गया था ... अभी नमूना डाउनलोड कर रहा हूं, लेकिन मैं यह समझना चाहूंगा कि एक्सेल क्यों नहीं मेरे कोड को पहचानता है
dwwilson66

WooHoo ... सैंपल शीट ने मदद की। मुझे एहसास हुआ कि मैंने कोड को पेस्ट कर दिया है और OBJECT विंडो को एक्सेल कर दिया है, न कि MODULE विंडो को। मैं अपनी कार्यपुस्तिका में अब हैश कर रहा हूँ!
dwwilson66 17

1
यह एक उत्कृष्ट उपकरण है।
जय किलेन

1
आप cutoffइसे फंक्शन पैरामीटर सूची में स्थानांतरित करके Public Function BASE64SHA1(ByVal sTextToHash As String, Optional ByVal cutoff As Integer = 8) और फ़ंक्शन के अंदर घोषणा को हटाकर एक अलग डिफ़ॉल्ट के साथ पैरामीटर और वैकल्पिक बना सकते हैं ।
कोर

9

मैं टकरावों के बारे में बहुत परवाह नहीं करता हूं, लेकिन एक चर-लंबाई वाले स्ट्रिंग क्षेत्र के आधार पर कमजोर कमजोर छद्म रेखाओं की आवश्यकता होती है। यहाँ एक पागल समाधान है कि अच्छी तरह से काम किया है:

=MOD(MOD(MOD(MOD(MOD(IF(LEN(Z2)>=1,CODE(MID(Z2,1,1))+10,31),1009)*IF(LEN(Z2)>=3,CODE(MID(Z2,3,1))+10,41),1009)*IF(LEN(Z2)>=5,CODE(MID(Z2,5,1))+10,59),1009)*IF(LEN(Z2)>=7,CODE(MID(Z2,7,1))+10,26),1009)*IF(LEN(Z2)>=9,CODE(MID(Z2,9,1))+10,53),1009)

Z2सेल जहां स्ट्रिंग है जिसे आप हैश करना चाहते हैं।

"एमओडी" वैज्ञानिक अंकन के अतिप्रवाह को रोकने के लिए हैं। 1009एक प्रधान है, कुछ भी एक्स का उपयोग कर सकता है ताकि एक्स * 255 < max_int_size। 10 मनमानी है; कुछ भी उपयोग करें। "एल्स" मूल्य मनमाना हैं (यहाँ पाई के अंक!); कुछ भी उपयोग करें। पात्रों का स्थान (1,3,5,7,9) मनमाना है; कुछ भी उपयोग करें।


2
ईमानदारी से यह सबसे सरल उत्तर है, मुझे संदेह है कि टकराव अधिकांश एक्सेल उपयोग मामलों के लिए एक मुद्दा है।
रोल

3

यथोचित छोटी सूची के लिए आप अंतर्निहित एक्सेल फ़ंक्शन का उपयोग करके एक स्क्रैम्बलर (खराब आदमी का हैश फ़ंक्शन) बना सकते हैं।

उदाहरण के लिए

 =CODE(A2)*LEN(A2) + CODE(MID(A2,$A$1,$B$1))*LEN(MID(A2,$A$1,$B$1))

यहां A1 और B1 एक रैंडम स्टार्ट लेटर और स्ट्रिंग लेंथ रखते हैं।

थोड़ा सा फिडिंग और चेकिंग और ज्यादातर मामलों में आप एक कामचलाऊ यूनिक आईडी प्राप्त कर सकते हैं।

यह कैसे काम करता है : सूत्र स्ट्रिंग के पहले अक्षर और मध्य-स्ट्रिंग से लिया गया एक निश्चित पत्र का उपयोग करता है और टकराव की संभावना को कम करने के लिए LEN () को एक 'फैनिंग फ़ंक्शन' के रूप में उपयोग करता है।

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

संपादित करें: यदि आपके तार में परिवर्तनशील लंबाई (जैसे पूर्ण नाम) होनी चाहिए, लेकिन निश्चित चौड़ाई वाले फ़ील्ड के साथ डेटाबेस रिकॉर्ड से खींच ली गई है, तो आप इसे इस तरह करना चाहेंगे:

 =CODE(TRIM(C8))*LEN(TRIM(C8))
       +CODE(MID(TRIM(C8),$A$1,1))*LEN(MID(TRIM(C8),$A$1,$B$1))

ताकि लंबाई एक सार्थक स्क्रैम्बलर हो।


1
बहुत बढ़िया जवाब! (: "गरीब आदमी का हैश फंक्शन", "कैविएट", "यह कैसे काम करता है" :)
natty के बारे में अखरोट

1
करने के लिए "कोई टकराव देखते हैं कि देखने के लिए परिणाम का निरीक्षण" आप बस की कोशिश कर सकते / परीक्षण इस आंकड़े> निकालें डुप्लिकेट चलाकर और यदि कोई हो तो देखते हैं। [जाहिर है / संभवतया, यदि आप डुप्लिकेट डुप्लिकेट करते हैं, तो आप इन पुनरावृत्तियों के लिए उपरोक्त फ़ंक्शन को तब तक फिर से चला सकते हैं जब तक कि कोई डुप्लिकेट नहीं बचा हो]
natty के बारे में अखरोट

2

मैं इसका उपयोग कर रहा हूं जो हर बार स्क्रिप्ट चलाने की आवश्यकता के बिना क्लैशिंग को रोकने के साथ बहुत अच्छे परिणाम देता है। मुझे 0 - 1 के बीच एक मान चाहिए।

=ABS(COS((CODE(MID(A2,ROUNDUP(LEN(A2)/9,0),1))*(CODE(MID(A2,ROUNDUP(LEN(A2)/5,0),1))+100)/CODE(MID(A2,ROUNDUP(LEN(A2)/3,0),1))*(CODE(MID(A2,ROUNDUP(LEN(A2)*8/9,0),1))+25)/CODE(MID(A2,ROUNDUP(LEN(A2)*6/9,0),1))*(CODE(MID(A2,ROUNDUP(LEN(A2)*4/9,0),1))-25))/LEN(A2)+CODE(A2)))

यह स्ट्रिंग से अक्षरों को उठाता है, उन अक्षरों में से प्रत्येक का मूल्य लेता है, एक मूल्य जोड़ता है (समान परिणाम देने वाले विभिन्न स्थानों में समान अक्षरों को रोकने के लिए), प्रत्येक को गुणा / विभाजित करता है और कुल पर एक COS फ़ंक्शन चलाता है।


1

आप यह कोशिश कर सकते हैं। दो स्तंभों पर एक छद्म # चलाएँ:

= + (और (ISBLANK (डी 3), ISBLANK (E3)), "", कोड (TRIM (डी 3 और ई 3)) * LEN (TRIM (डी 3 और ई 3)) + कोड (MID (TRIM (डी 3 और ई 3), $ A $ 1 * LEN (डी 3 और ई 3), 1) इंटे (एलईएन (टीआरआईएम (डी 3 और ई 3)) $ बी $ 1)

जहाँ A1 और B1 रैंडम बीजों को मैन्युअल रूप से दर्ज करते हैं: 0


0

मेरी जानकारी में एक्सेल में कोई हैश फंक्शन बिल्ड नहीं है - आपको वीबीए में एक यूजर डिफाइन्ड फंक्शन के रूप में निर्माण करना होगा।

हालाँकि, कृपया ध्यान दें कि आपके उद्देश्य के लिए मुझे हैश का उपयोग करना आवश्यक नहीं है या वास्तव में फायदेमंद है! VLOOKUPयह केवल 256 बाइट्स पर काम करेगा क्योंकि यह एक छोटे से हैश पर होगा। ज़रूर, यह एक छोटा सा धीमा हो सकता है - बिट जो कि इतना छोटा है कि यह अथाह है। और फिर हैश मूल्यों को जोड़ना आपके लिए अधिक प्रयास है - और एक्सेल के लिए ...


हाँ ... मुझे लगता है कि पता है, लेकिन सिर्फ एक प्रस्तुति के दृष्टिकोण से, मैं बल्कि प्रदर्शित करता हूँ, कहते हैं, 15 बाइट हैश की है कि titleमेरे बचे हुए बाएँ फलक में 256 बाइट्स ...
dwwilson66
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.