2015-03-16 12 views
5

का समर्थन करता है मैं तारों के हैश मानों का उपयोग करके स्थान सहेजने की कोशिश कर रहा हूं। मेरे पास एक बहुत ही विशिष्ट आवश्यकता है, जिसका सरलीकृत विवरण निम्नानुसार है:क्या कोई स्ट्रिंग हैश फ़ंक्शन है जो एच (x) + h (y) = h (x + y)

मेरे पास स्ट्रिंग मानों के दो सेट हैं और रनटाइम में एक मान प्रदान किया जाता है। मुझे दूसरे सेट से सभी तारों की एक सूची प्राप्त करने की आवश्यकता है जो पहले सेट से स्ट्रिंग के साथ शुरू होता है और क्वेरी मान के साथ समाप्त होता है। यहाँ एक काफी सरल बनाया प्रतिनिधित्व और वर्णन है:

set1: 
my_test_val_1 
my_test_val_2 

set2: 
my_test_val_1_extended_to_another_value 
my_test_val_2_extended_as_well 

मेरा उद्देश्य के रूप में इन सेटों की हैश मान रखने के लिए है:

set1: 
hash(my_test_val_1) 
... 

set2: 
hash(my_test_val_1_extended_to_another_value) 

अंतरिक्ष और जब '_extended_to_another_value' एक प्रश्न के रूप में आता पर बचाने के लिए, ऐसा करने के लिए योग पर वितरण संपत्ति के साथ हैश समारोह का उपयोग करें:

hash(my_test_val_1) + hash('_extended_to_another_value') = hash_value_to_search 

मेरे खोज एक हैश समारोह है कि इस संपत्ति सबसे पी में नाकाम रही है का समर्थन करता है खोजने के लिए प्रयास करता है robably कारण खोज के लिए सही कीवर्ड का उपयोग नहीं है, इसलिए करने के लिए भले ही आप क्या मैं ऊपर वर्णन कर रहा हूँ के लिए सही शब्दों का वर्णन कर सकते हैं, यह मदद मिलेगी

+5

आप * सिर्फ * हैश रखने पर निर्भर कर रहे हैं:

यहाँ ऑनलाइन हैश डेटाबेस का एक उदाहरण है? हैश टकराव से निपटने के लिए आपकी योजना क्या है? –

+0

परिणामी हैश फ़ंक्शन से आपको किन गुणों की आवश्यकता होती है? अंतिम हैश के लिए कितने बिट्स का उपयोग किया जा सकता है? – dhke

+2

"दूसरे सेट से सभी स्ट्रिंग्स की सूची प्राप्त करने की आवश्यकता है जो पहले सेट से स्ट्रिंग के साथ शुरू होता है और क्वेरी मान के साथ समाप्त होता है।" [क्या आप एक ट्राई की तलाश में हैं?] (Http://en.wikipedia.org/wiki/Trie) – dasblinkenlight

उत्तर

3

यहाँ एक है:

import java.util.Random; 
public class StringHasher { 
    private static int[] CHAR_HASHES = new int[65536]; 
    static { 
     Random rng = new Random(); 
     for(int k = 0; k < 65536; k++) 
      CHAR_HASHES[k] = rng.nextInt(); 
    } 
    public static int hash(String s) { 
     int result = 0; 
     for(int k = 0; k < s.length(); k++) { 
      result += CHAR_HASHES[s.charAt(k)]; 
     } 
     return result; 
    } 
} 

ऐसा लगता है कि ऐसे किसी भी हैश को स्ट्रिंग के घटक वर्णों के सभी हैंश जोड़कर बनाया जाना चाहिए - अन्यथा उदाहरण के लिए h("hello") = h("h") + h("e") + h("l") + h("l") + h("o") नहीं होगा।

नोट: इसका मतलब है कि आपके पास बहुत टक्कर-प्रतिरोधी हैश नहीं हो सकता है, क्योंकि प्रत्येक स्ट्रिंग वाले प्रत्येक स्ट्रिंग में पिछले पैराग्राफ के समान ही हैश होगा।

प्रत्येक एकल-वर्ण स्ट्रिंग के हैश के लिए यादृच्छिक मान चुनना औसत पर सर्वोत्तम संभव टकराव प्रतिरोध के करीब प्रदान करना चाहिए। यह स्मृति की 256 कीबी बर्बाद करता है, और यह सबसे तेज़ संभव तरीका नहीं है, और दोहराने योग्य नहीं है, लेकिन यह सबूत-अवधारणा के लिए पर्याप्त है।

+1

+1। मैं CHAR_HASHES भरने के लिए प्राइम का उपयोग करने पर विचार करता हूं। – Krystian

+0

@ क्रिस्टियन मुझे नहीं पता कि अच्छी टक्कर प्रतिरोध (लेकिन यादृच्छिक संख्याओं के काम) के लिए चरित्र हैश चुनने के बारे में कैसे जाना है। – immibis

-2

आप कुछ मुख्यधारा हैश एल्गोरिदम का उपयोग कर सकते हैं और इसे ऑनलाइन डेटाबेस के साथ हैक करने का प्रयास कर सकते हैं। यदि एक्स और वाई काफी कम हैं तो आप इसे एमडी 5 या एसएचए ऑनलाइन क्रैक किए गए हैंश डेटाबेस में पा सकते हैं और यदि आप इसे अपने एल्गोरिदम के साथ आगे बढ़ने से पहले इसे डिस्फर कर सकते हैं।

यदि आपका आवेदन ऑनलाइन है तो यह उस दृष्टिकोण का उपयोग कर सकता है। नकारात्मकता यह है कि कुछ कोने के मामलों में आपको गलत मान मिल सकता है जिसमें एक ही हैश कोड सही है, लेकिन इसकी संभावना बहुत कम है।

यह मूल रूप से एक हैक है, लेकिन आप अपनी आवश्यकता के साथ उस तरह की चीजें कर रहे हैं, इसलिए यह आपके लिए स्वीकार्य हो सकता है।

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