2009-12-22 3 views
9

मैं निम्नलिखित गुणों के साथ एक पर्ल स्ट्रिंग चेकसम समारोह के लिए देख रहा हूँ:0..2^32-1 रेंज में पर्ल पैदा मूल्यों में एक त्वरित स्ट्रिंग चेकसम समारोह

  • इनपुट: अपरिभाषित के यूनिकोड स्ट्रिंग लंबाई ($string)
  • आउटपुट: अहस्ताक्षरित पूर्णांक ($hash), जिसके लिए 0 <= $hash <= 2^32-1 रखती

छद्म कोड (0 4294967295, एक 4-बाइट MySQL अहस्ताक्षरित int के आकार मिलान करने के लिए):

sub checksum { 
    my $string = shift; 
    my $hash; 
    ... checksum logic goes here ... 
    die unless ($hash >= 0); 
    die unless ($hash <= 4_294_967_295); 
    return $hash; 
} 

आदर्श रूप में चेकसम समारोह को चलाने के लिए त्वरित किया जाना चाहिए और कुछ हद तक लक्ष्य अंतरिक्ष (0 .. 2^32-1) टकराव से बचने के लिए समान रूप से मान उत्पन्न करनी चाहिए। इस एप्लिकेशन में यादृच्छिक टकराव पूरी तरह से घातक हैं, लेकिन जाहिर है, मैं उन हद तक उनसे बचना चाहता हूं कि यह संभव है।

इन आवश्यकताओं को देखते हुए, इसे हल करने का सबसे अच्छा तरीका क्या है?

+0

आप सभी संभव तार के साथ टकराव से बचने के लिए, लेकिन केवल एक 4 अरब संभव है चाहता हूँ हज़म? एक पूर्णांक का उपयोग क्यों महत्वपूर्ण है? एमडी 5 की तरह कुछ इस्तेमाल करने के बारे में, भले ही आपको पच को स्ट्रिंग के रूप में स्टोर करना पड़े? –

+1

"आप सभी संभावित तारों के साथ टकराव से बचना चाहते हैं" - नहीं, जैसा कि मैंने सवाल में कहा है, "बस उनसे बचाना चाहते हैं कि यह संभव है"। – knorv

+0

"एक पूर्णांक का उपयोग क्यों महत्वपूर्ण है?" - जैसा कि सवाल में बताया गया है कि चेकसम "एक 4-बाइट MySQL हस्ताक्षरित int" में संग्रहीत किया जाएगा। – knorv

उत्तर

11

कोई हैश फ़ंक्शन पर्याप्त होगा - इसे 4-बाइट्स पर छोटा कर दें और किसी संख्या में कनवर्ट करें। अच्छे हैश फ़ंक्शंस में एक यादृच्छिक वितरण होता है, और यह वितरण स्थिर रहेगा चाहे आप स्ट्रिंग को छोटा कर दें।

मैं Digest::MD5 का सुझाव देता हूं क्योंकि यह सबसे तेज़ हैश कार्यान्वयन है जो पर्ल के साथ मानक के रूप में आता है। स्ट्रिंग :: सीआरसी, जैसा कि पिम उल्लेख है, सी में भी लागू किया गया है और तेजी से होना चाहिए।

use Digest::MD5 qw(md5); 
my $str = substr(md5("String-to-hash"), 0, 4); 
print unpack('L', $str); # Convert to 4-byte integer (long) 
+1

बी :: हैश कोर पर्ल के साथ आता है, आंतरिक कोर हैश फ़ंक्शन का उपयोग करता है, एमडी 5 से तेज़ है और एक हेक्सिफाइड 32-बिट पूर्णांक देता है। लेकिन एमडी 5 के रूप में सुरक्षित नहीं है। – rurban

4

यह नहीं पता कि यह कितनी जल्दी है, लेकिन आप String::CRC आज़मा सकते हैं।

3

से perldoc -f unpack:

यहाँ कैसे हैश की गणना और यह एक पूर्णांक में बदलने के लिए है

 For example, the following computes the same number as the 
     System V sum program: 

      $checksum = do { 
       local $/; # slurp! 
       unpack("%32W*",<>) % 65535; 
      }; 
+0

यादृच्छिक वितरण के लिए सभी बिट्स का यह 32 बिट रकम बहुत खराब हैश मान है। कोई हैश फ़ंक्शन बेहतर है, यहां तक ​​कि सबसे सरल भी। – rurban

+0

निश्चित रूप से, लेकिन यह वही समस्या है जो सिस्टम V 'sum' प्रोग्राम में है। अनुच्छेद देखें। या आप बहस कर रहे हैं कि 'योग' तर्कसंगत रूप से टूटा हुआ है? उस स्थिति में, यह पर्ल के बारे में नहीं है। –

+0

'sum' जितना तेज़ होगा उतना तेज़ होगा, जैसा ऊपर बताया गया है, यह बहुत मजबूत नहीं है। आप आकार का उपयोग कर इसे थोड़ा सुधार सकते हैं, उदा। '$ _ = <>; अनपैक ("% 32W *", $ _)% 65535। लंबाई ($ _) '। कुछ भी जो अधिक मजबूत होने की आवश्यकता है उसे 'डाइजेस्ट :: एमडी 5' या' डाइजेस्ट :: एसएचए 'आदि का उपयोग करना चाहिए। –

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