2010-05-01 18 views
9

मैं वर्तमान में लगभग 15 यूआरएल चलाने और उनके एमडी 5 हैश को सत्यापित करने के लिए md5_file() का उपयोग करता हूं। क्या कोई तरीका है कि मैं इसे तेज़ी से कर सकता हूं? उन सभी के माध्यम से चलाने में बहुत लंबा समय लगता है।md5_file() को तेज़ बनाने का एक तरीका?

+0

"लगभग 15 यूआरएल के माध्यम से चलाएं" का अर्थ है 15 एमआरएल के साथ एक लूप में 'md5_file (' http: //some.url/foo ')' जैसे कुछ? वे "फाइलें" कितनी बड़ी हैं? – VolkerK

+0

हाँ, यह बिल्कुल है। मैं उन्हें एक MySQL डेटाबेस से खींचता हूं और फिर उन्हें लूप में md5_file ($ परिणाम) में चलाता हूं। फाइलें बहुत छोटी हैं, और वास्तव में कोई प्रदर्शन आउटपुट नहीं है, यूआई नहीं है, – Rob

+0

देखे जाने पर बस एक खाली सफेद पृष्ठ मुद्दा यह है कि आप समानांतर के बजाय अनुक्रम में हैंश की गणना कर रहे हैं; 'md5_file' बाधा नहीं है। इसके अलावा, निश्चित रूप से एक खाली फ़ाइल का हैश हमेशा एक जैसा होगा। – salathe

उत्तर

15

शायद आप इसे अनुक्रमिक रूप से अभी कर रहे हैं। अर्थात। डेटा 1 प्राप्त करें, डेटा 1 को संसाधित करें, डेटा 2 प्राप्त करें, डेटा 2 प्रक्रिया करें ... और बाधा डेटा स्थानांतरण हो सकती है।
आप थोड़ा सा समानांतर करने के लिए curl_multi_exec() का उपयोग कर सकते हैं। या तो CURLOPT_WRITEFUNCTION पंजीकृत करें और डेटा के प्रत्येक हिस्से को संसाधित करें (एमडी 5() के बाद से मुश्किल डेटा के एक हिस्से पर काम करता है)।
या कर्ल हैंडल की जांच करें जो पहले ही समाप्त हो चुके हैं और फिर उस हैंडल के डेटा को संसाधित करते हैं।

संपादित करें: त्वरित & गंदा उदाहरण hash extension (जो वृद्धिशील हैश के लिए कार्य प्रदान करता है) और एक php5.3+ closure का उपयोग कर:

$urls = array(
    'http://stackoverflow.com/', 
    'http://sstatic.net/so/img/logo.png', 
    'http://www.gravatar.com/avatar/212151980ba7123c314251b185608b1d?s=128&d=identicon&r=PG', 
    'http://de.php.net/images/php.gif' 
); 

$data = array(); 
$fnWrite = function($ch, $chunk) use(&$data) { 
    foreach($data as $d) { 
    if ($ch===$d['curlrc']) { 
     hash_update($d['hashrc'], $chunk); 
    } 
    } 
}; 

$mh = curl_multi_init(); 
foreach($urls as $u) { 
    $current = curl_init(); 
    curl_setopt($current, CURLOPT_URL, $u); 
    curl_setopt($current, CURLOPT_RETURNTRANSFER, 0); 
    curl_setopt($current, CURLOPT_HEADER, 0); 
    curl_setopt($current, CURLOPT_WRITEFUNCTION, $fnWrite); 
    curl_multi_add_handle($mh, $current); 
    $hash = hash_init('md5'); 
    $data[] = array('url'=>$u, 'curlrc'=>$current, 'hashrc'=>$hash); 
} 

$active = null; 
//execute the handles 
do { 
    $mrc = curl_multi_exec($mh, $active); 
} while ($mrc == CURLM_CALL_MULTI_PERFORM); 

while ($active && $mrc == CURLM_OK) { 
    if (curl_multi_select($mh) != -1) { 
    do { 
     $mrc = curl_multi_exec($mh, $active); 
    } while ($mrc == CURLM_CALL_MULTI_PERFORM); 
    } 
} 

foreach($data as $d) { 
    curl_multi_remove_handle($mh, $d['curlrc']); 
    echo $d['url'], ': ', hash_final($d['hashrc'], false), "\n"; 
} 
curl_multi_close($mh); 

(परिणाम हालांकि जाँच नहीं की है ... यह केवल एक प्रारंभिक बिंदु)

+2

+1। समानांतर डाउनलोड संभवतः यहां एक बड़ी जीत है। आप वास्तव में 'md5sum' सीएलआई कमांड (उदाहरण के लिए' exec ('bash -c "md5sum file1> file1.md5 और"') ') का उपयोग कर md5 भाग को समानांतर कर सकते हैं, या PHP के pcntl_fork() जैसे कुछ का उपयोग कर सकते हैं md5_sum() को कई कॉल फोर्क करने के लिए। इन दोनों में उनकी कमी है, लेकिन सही संदर्भ में, वे करने के लिए सबसे अच्छी बात हो सकती है। –

+0

और मुझे यह स्वीकार करना होगा कि मैंने यह भी जांच नहीं की है कि कॉलबैक निष्पादित होने पर डाउनलोड वास्तव में जारी रहता है या नहीं। लेकिन चूंकि डेटा भाग माना जाता है कि मुझे लगता है कि इससे कोई फर्क नहीं पड़ता (ज्यादा)। – VolkerK

0

एमडी 5 एल्गोरिदम जितना तेज़ हो सकता है उतना तेज़ है, और यूआरएल लाने जितना तेज़ हो सकता है (फाइलें बहुत बड़ी हैं या आपके पास धीमा कनेक्शन है) धीमा है। तो नहीं। आप इसे तेजी से नहीं बना सकते हैं।

0

खैर स्पष्ट रूप से आप तेजी से बनाने के लिए md5_file() साथ कुछ नहीं कर सकते, हालांकि, आप कुछ micro-optimizations या कोड को फिर से फैक्टरिंग का उपयोग कुछ गति लाभ प्राप्त करने के लिए कर सकते हैं लेकिन फिर आप में निर्मित समारोह md5_file() में तेजी लाने नहीं कर सकते।

+1

... निश्चित रूप से, कुछ माइक्रो-ऑप्टिमाइज़ेशन अपने रनटाइम के 2 मिलीसेकंड दाढ़ी दे सकते हैं। शायद। या वह सिर्फ यूआरएल को समानांतर में खींच सकता है और कुछ सेकंड बचा सकता है। "सूक्ष्म अनुकूलन" लगभग प्रयास के लायक नहीं हैं। –

+0

@ फ्रैंक, यह वास्तव में प्रश्न में कोड शामिल करने के लिए संपादित किए जाने वाले प्रश्न से पहले पोस्ट किया गया था (जो, जब तक कोड जोड़ा नहीं गया था, मूल रूप से पूछा गया कि md5_file() को कैसे गति दें)। –

0

नहीं। चूंकि यह एक अंतर्निहित कार्य है क्योंकि इसे तेज़ी से बनाने का कोई तरीका नहीं है।

लेकिन यदि आपका कोड MD5ing से पहले फ़ाइलों को डाउनलोड कर रहा है, तो आपके डाउनलोड को तेज़ी से अनुकूलित करना संभव हो सकता है। यदि आप समय से पहले आकार जानते हैं तो इसे लिखने से पहले फ़ाइल के आकार (ftruncate का उपयोग करके) को सेट करके आप एक छोटी गति वृद्धि भी देख सकते हैं।

इसके अलावा, अगर फाइलें स्मृति में पकड़ने के लिए पर्याप्त छोटी हैं और आपके पास पहले से ही स्मृति में है (क्योंकि उन्हें डाउनलोड किया गया है, या किसी अन्य उद्देश्य के लिए पढ़ा जा रहा है) तो आप स्मृति में इसे संचालित करने के लिए md5 का उपयोग कर सकते हैं md5_file के बजाय, जिसे डिस्क से फिर से पढ़ना आवश्यक है।

0

संभवतः आप एक ही समय में एक ही यूआरएल की जांच कर रहे हैं? क्या आप यूआरएल के लिए अंतिम संशोधित शीर्षलेख देख सकते हैं? यदि पृष्ठ की जांच की जा रही है तो एमडी 5 की पुन: गणना करने की आवश्यकता नहीं होगी।

आप पृष्ठों को अतुल्यकालिक रूप से भी अनुरोध कर सकते हैं ताकि उन्हें सीरियल के बजाए समानांतर में संसाधित किया जा सके, जिसे इसे तेज करना चाहिए।

0

एमडी 5 एल्गोरिदम की गति रैखिक है। इनपुट जितना बड़ा होगा, उतना ही समय लगेगा, इसलिए यदि फ़ाइल बड़ी है, तो आप वास्तव में ऐसा नहीं कर सकते हैं।

अब, जैसा कि वोल्करके ने पहले से ही सुझाव दिया है, समस्या सबसे अधिक संभावना है कि एमडी 5 हैशिंग लेकिन नेट पर फ़ाइल को पुनर्प्राप्त करने और पढ़ने की संभावना नहीं है।

0

मुझे here अनुकूलित करने का एक बहुत अच्छा सुझाव दिखाई देता है। यह विशेष रूप से बड़ी फ़ाइलों के लिए काम करेगा, जहां md5_file फ़ाइल पढ़ रहा है और यह फ़ंक्शन बस प्रत्येक फ़ाइल के दूसरे बाइट की तुलना कर रहा है।

0

समझाते हुए कि आप क्या करना चाहते हैं, इससे मदद मिलेगी। यदि आप अपने एमडी 5 हैश के साथ एक फाइल को सत्यापित करना चाहते हैं:

यह एक सुरक्षित तरीका नहीं है क्योंकि यह Collision attack से प्रवण है। आपको एकाधिक हैंश (शायद फ़ाइल को विभाजित करके) या अन्य हैश विधियों का उपयोग करना चाहिए।

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