इसके साथ ही कई डाइजेस्ट (md5, sha256) की गणना करें?


25

इस धारणा के तहत कि डिस्क I / O और मुफ्त रैम एक अड़चन है (जबकि सीपीयू समय सीमा नहीं है), क्या एक उपकरण मौजूद है जो एक साथ कई संदेश डाइजेस्ट की गणना कर सकता है?

मैं विशेष रूप से समानांतर में बड़ी फ़ाइलों (गीगाबाइट्स में आकार) के एमडी -5 और एसएचए -255 डिजीज की गणना में दिलचस्पी रखता हूं। मैंने कोशिश की है openssl dgst -sha256 -md5, लेकिन यह केवल एक एल्गोरिथ्म का उपयोग करके हैश की गणना करता है।

अपेक्षित व्यवहार के लिए छद्म कोड:

for each block:
    for each algorithm:
        hash_state[algorithm].update(block)
for each algorithm:
    print algorithm, hash_state[algorithm].final_hash()

आप पृष्ठभूमि में सिर्फ एक उदाहरण शुरू कर सकते हैं, फिर दोनों हैश समानांतर में चलते हैं:for i in file1 file2 …; do sha256 "$i"& md5sum "$i"; done
मार्को

2
@ मार्को उस दृष्टिकोण के साथ समस्या यह है कि एक कमांड दूसरे से तेज हो सकती है, जिसके परिणामस्वरूप एक डिस्क कैश खाली हो जाता है और उसी डेटा के साथ बाद में रिफिल हो जाता है।
लेकेनस्टाइन

1
यदि आप डिस्क कैश के बारे में चिंतित हैं, तो आप फ़ाइल में सिर्फ एक बार पढ़ सकते हैं: for i in file1 file2 …; do tee < "$i" >(sha256sum) | md5sum ; doneफिर आपको फ़ाइल नाम को चिह्नित करने के लिए अतिरिक्त कोड जोड़ना होगा, क्योंकि यह मानक इनपुट के रूप में भेजा जाता है md5sumऔर sha256sum
मार्को

जवाबों:


28

से देखें pee(" tee standard input to pipes") moreutils। यह मूल रूप से मार्को की teeकमांड के बराबर है , लेकिन टाइप करने के लिए थोड़ा सरल है।

$ echo foo | pee md5sum sha256sum
d3b07384d113edec49eaa6238ad5ff00  -
b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c  -
$ pee md5sum sha256sum <foo.iso
f109ffd6612e36e0fc1597eda65e9cf0  -
469a38cb785f8d47a0f85f968feff0be1d6f9398e353496ff7aa9055725bc63e  -

अच्छा आदेश! मेरे पास पहले से ही यह बहुत उपयोगी पैकेज स्थापित है, इस अजीब नाम वाली उपयोगिता का पता नहीं था।
लेकेनस्टाइन

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

दुर्भाग्य से, मेरे डेबियन सिस्टम पर moreutilsविरोध GNU parallel... हालांकि, यह जानना अच्छा है कि ऐसा उपकरण है।
लियोरी

@Lekensteyn: मुझे पैकेज स्तर पर एक विरोधाभास मिलता है (यानी aptitudeमुझे एक ही समय में दोनों पैकेज नहीं देने चाहिए)।
लियोरी

@ लियोरी बहुत बुरा है कि डेबियन ने इसे इस तरह से लागू किया, यह इस पर एक बग दर्ज करने के लिए लायक हो सकता है। आर्क लिनक्स पर moreutils-parallelसंघर्ष से बचने के लिए एक नाम है।
लेकेन्स्टाइन

10

आप forअलग-अलग फ़ाइलों पर लूप का उपयोग कर सकते हैं और फिर tee विभिन्न चेकसमर्स को पाइप करने के लिए प्रक्रिया प्रतिस्थापन (दूसरों के बीच बाश और ज़ीश में काम करता है) के साथ संयुक्त का उपयोग कर सकते हैं ।

उदाहरण:

for file in *.mkv; do
  tee < "$file" >(sha256sum) | md5sum
done

आप दो से अधिक चेकसमर्स का उपयोग भी कर सकते हैं:

for file in *.mkv; do
  tee < "$file" >(sha256sum) >(sha384sum) | md5sum
done

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

for file in *.mkv; do
  echo "$file"
  tee < "$file" >(sha256sum) >(sha384sum) | md5sum
  echo
done > hashfilelist

1
*sumउपकरणों के परिवार के साथ आउटपुट को अनुकूल बनाने के लिए , इस सेड एक्सप्रेशन का उपयोग किया जा सकता है: sed "s;-\$;${file//;/\\;};( -फ़ाइल नाम द्वारा अनुगामी को प्रतिस्थापित किया जाता है, लेकिन यह सुनिश्चित करें कि फ़ाइल नाम ठीक से बच जाए)।
लेकेन्स्टाइन

AFAICS, यह केवल में काम करता है zsh। Ksh93 और बैश में, sha256sum का आउटपुट md5sum में जाता है। आप चाहेंगे कि: { tee < "$file" >(sha256sum >&3) | md5sum; } 3>&1। रिवर्स समस्या के लिए unix.stackexchange.com/q/153896/22565 देखें ।
स्टीफन चेज़लस

6

यह अफ़सोस की बात है कि ओपनसेल उपयोगिता कई डाइजेस्ट कमांड को स्वीकार नहीं करती है; मुझे लगता है कि कई फाइलों पर एक ही कमांड का प्रदर्शन एक अधिक सामान्य उपयोग पैटर्न है। FWIW, मेरे सिस्टम (Mepis 11) पर खुलने वाली उपयोगिता का संस्करण केवल sha और sha1 के लिए है, अन्य sha के किसी भी संस्करण के लिए नहीं। लेकिन मेरे पास sha256sum, साथ ही md5sum नामक एक कार्यक्रम है।

यहाँ एक साधारण पायथन प्रोग्राम, dual_hash.py है, जो आपको चाहिए। 64k का ब्लॉक आकार मेरी मशीन के लिए इष्टतम प्रतीत होता है (Intel Pentium 4 2.00GHz 2G RAM के साथ), YMMV। छोटी फ़ाइलों के लिए, इसकी गति लगभग md5sum और उत्तराधिकार में sha256sum चलाने के समान है। लेकिन बड़ी फ़ाइलों के लिए यह काफी तेज है। उदाहरण के लिए, 1967063040 बाइट फ़ाइल (एमपी फाइलों से भरे एसडी कार्ड की एक डिस्क छवि) पर, md5sum + sha256sum लगभग 1m44.9s लेता है, dual_hash.py 1m0.33vs लेता है।

dual_hash.py

#! /usr/bin/env python

''' Calculate MD5 and SHA-256 digests of a file simultaneously

    Written by PM 2Ring 2014.10.23
'''

import sys
import hashlib

def digests(fname, blocksize):
    md5 = hashlib.md5()
    sha = hashlib.sha256()
    with open(fname, 'rb') as f:
        while True:
            block = f.read(blocksize)
            if not block:
                break
            md5.update(block)
            sha.update(block)

    print("md5: %s" % md5.hexdigest())
    print("sha256: %s" % sha.hexdigest())

def main(*argv):
    blocksize = 1<<16 # 64kB
    if len(argv) < 2:
        print("No filename given!\n")
        print("Calculate md5 and sha-256 message digests of a file.")
        print("Usage:\npython %s filename [blocksize]\n" % sys.argv[0])
        print("Default blocksize=%d" % blocksize)
        return 1

    fname = argv[1]

    if len(argv) > 2:
        blocksize = int(sys.argv[2])

    print("Calculating MD5 and SHA-256 digests of %r using a blocksize of %d" % (fname, blocksize))
    digests(fname, blocksize)

if __name__ == '__main__':
    sys.exit(main(*sys.argv))

मैं इस कार्यक्रम के एक C / C ++ संस्करण एक छोटे से तेजी से किया जाएगा लगता है, लेकिन बहुत ज्यादा नहीं है, क्योंकि काम के सबसे hashlib मॉड्यूल है, जिसके द्वारा किया जा रहा है है सी (या सी ++) में लिखा। और जैसा कि आपने ऊपर उल्लेख किया है, बड़ी फ़ाइलों के लिए टोंटी आईओ गति है।


2.3G की फ़ाइल के लिए, इस संस्करण की तुलना md5sumऔर sha256sumसंयुक्त (4.7s + 14.2s बनाम 18.7s की तुलना में इस पायथन स्क्रिप्ट के लिए, कैश में फ़ाइल; ठंड रन के लिए 33.6s) की तुलना की गई है। 64KiB बनाम 1MiB ने स्थिति को नहीं बदला। कोड टिप्पणी के साथ, 5.1s को md5 (n = 3), 14.6s पर sha1 (n = 3) पर खर्च किया गया था। 8 जीबी रैम के साथ i5-460M पर परीक्षण किया गया। मुझे लगता है कि अधिक धागे का उपयोग करके इसे और बेहतर बनाया जा सकता है।
लेकेन्स्टाइन

C या C ++ शायद यह मायने नहीं रखेगा कि OpenSSL मॉड्यूल में जितना भी रनटाइम खर्च किया जाता है (उतना हैशलीब द्वारा उपयोग किया जाता है)। अधिक थ्रेड्स गति में सुधार करते हैं, इस पोस्ट को बहु-थ्रेडेड पायथन स्क्रिप्ट के बारे में देखें ।
लेकेन्स्टाइन

@PM 2Ring - बस एक नोट। आपके डाइजेस्ट () फ़ंक्शन में प्रिंट स्टेटमेंट्स के बाद, आपको कम से कम शा को साफ़ करने की आवश्यकता है। मैं यह नहीं कह सकता कि आपको स्पष्ट md5 चाहिए या नहीं। मैं सिर्फ "डेल श" का उपयोग करूंगा। यदि आप नहीं करते हैं, तो पहले के बाद की हर फाइल में एक गलत हैश होगा। इसे साबित करने के लिए, एक tmp dir बनाएं और उसमें एक फाइल कॉपी करें। अब उस फ़ाइल की 2 प्रतियां बनाएं, और अपनी स्क्रिप्ट चलाएं। आपको 3 अलग-अलग हैश मिलेंगे, जो आप नहीं चाहते। संपादित करें: मैंने सोचा कि फ़ंक्शन फ़ाइलों के एक सेट पर पढ़ रहा था, न कि एक बार में एक ही फ़ाइल को पढ़ रहा था ... इस उपयोग के लिए उपेक्षा। ;)
टेरी वेंड्ट

1
@TerryWendt तुम मुझे वहाँ एक दूसरे के लिए चिंता थी। :) हां, digestsप्रत्येक कॉल पर केवल एक ही फ़ाइल संसाधित करता है। तो भले ही आपने इसे लूप में कॉल किया हो, यह प्रत्येक कॉल पर नए md5 और sha संदर्भ देगा। FWIW, आप मेरे फिर से शुरू SHA-256 हैश का आनंद ले सकते हैं ।
बजे PM 2Ring

5

आप हमेशा GNU समानांतर जैसे कुछ का उपयोग कर सकते हैं :

echo "/path/to/file" | parallel 'md5sum {} & sha256sum {}'

वैकल्पिक रूप से, बस पृष्ठभूमि में दो में से एक चलाएं:

md5sum /path/to/file & sha256sum /path/to/file

या, आउटपुट को अलग-अलग फ़ाइलों में सहेजें और पृष्ठभूमि में कई काम चलाएं:

for file in *; do
    md5sum "$file" > "$file".md5 &
    sha256sum "$file" > "$file".sha &
done

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


1
मार्को की टिप्पणी देखें, मेरी चिंता यह है कि हालांकि कमांड समानांतर होगा, धीमी डिस्क एक ही डेटा के लिए दो बार एक्सेस की जाती है।
लेकेन्स्टाइन

लेकिन क्या डिस्क कैश का अस्तित्व आपकी चिंताओं को अनावश्यक नहीं बना देगा?
ट्विंकल

2
@Twinkles ऊपर दिए गए Lekensteyn को उद्धृत करने के लिए, "उस दृष्टिकोण के साथ समस्या यह है कि एक कमांड दूसरे की तुलना में तेज हो सकती है, जिसके परिणामस्वरूप एक डिस्क कैश खाली हो जाती है और उसी डेटा के साथ बाद में रिफिल हो जाती है।"
मैट नॉर्डहॉफ

2
@MattNordhoff फिर भी एक बुद्धिमान I / O अनुसूचक को एक और बात ध्यान देनी चाहिए और इसके लिए अनुकूलन करना चाहिए। कोई सोच सकता है: "इस परिदृश्य को ध्यान में रखना I / O अनुसूचक के लिए कितना कठिन हो सकता है?" लेकिन पर्याप्त भिन्न परिदृश्यों के साथ I / O अनुसूचक को ध्यान में रखना चाहिए, यह अचानक एक कठिन समस्या बन जाती है। इसलिए मैं मानता हूं कि किसी को यह नहीं समझना चाहिए कि कैशिंग समस्या का ध्यान रखेगा।
कास्परड

1
IO को मानते हुए इसमें शामिल किसी भी उपकरण की तुलना में काफी धीमा है, दोनों उपकरण IO के कारण समान गति से धीमा होना चाहिए। इसलिए, यदि एक टूल दूसरे से अधिक डेटा के कुछ ब्लॉक प्राप्त करने का प्रबंधन करता है, तो दूसरा टूल डिस्क कैश में डेटा का उपयोग करके गणनाओं के साथ जल्दी पकड़ लेगा। यह सिद्धांत है, मैं इसे साबित करने के लिए कुछ प्रायोगिक परिणाम देखना पसंद करूंगा ...
liori

3

जिज्ञासा से बाहर कि क्या एक बहु-थ्रेडेड पायथन स्क्रिप्ट चल रहे समय को कम कर देगी, मैंने इस digest.pyस्क्रिप्ट को बनाया जो उपयोग करता है threading.Thread, threading.Queueऔर hashlibकई फ़ाइलों के लिए हैश की गणना करने के लिए।

मल्टी-थ्रेडेड पायथन कार्यान्वयन वास्तव में peeकोर्यूटिल्स के साथ उपयोग करने की तुलना में थोड़ा तेज है । दूसरी ओर जावा है ... मेह। परिणाम इस प्रतिबद्ध संदेश में उपलब्ध हैं :

तुलना के लिए, 2.3 GiB (मिन / एवीजी / अधिकतम / एसडी सेकंड के लिए n = 10) की फाइल के लिए:

  • pee sha256sum md5sum <फाइल: 16.5 / 16.9 / 17.4 / .305
  • python3 digest.py -sha256 -md5 <फ़ाइल: 13.7 / 15.0 / 18.7 / 1.77
  • python2 digest.py -sha256 -md5 <फ़ाइल: 13.7 / 15.9 / 18.7 /1/ 64
  • जैकसम-ए sha256 + md5 -F '#CHECKSUM {i} #FILENAME': 32.7 / 37.1 / 50 / 6.91

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

$ ./digest.py -sha256 -md5 digest.py
c217e5aa3c3f9cfaca0d40b1060f6233297a3a0d2728dd19f1de3b28454975f2  digest.py
b575edf6387888a68c93bf89291f611c  digest.py
$ ./digest.py -sha256 -md5 <digest.py
c217e5aa3c3f9cfaca0d40b1060f6233297a3a0d2728dd19f1de3b28454975f2  -
b575edf6387888a68c93bf89291f611c  -
$ pee sha256sum md5sum <digest.py
c217e5aa3c3f9cfaca0d40b1060f6233297a3a0d2728dd19f1de3b28454975f2  -
b575edf6387888a68c93bf89291f611c  -

मैं तुलना करने का सुझाव देने जा रहा था pee "openssl sha256" "openssl md5" < file, लेकिन, ईमानदारी से, मैंने अभी इसकी कोशिश की, और यह डाइजेस्ट्रो को हरा नहीं पाया। हालांकि इसने अंतर को कम कर दिया।
मैट नॉर्डहॉफ़

1

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

यह बड़ी फाइल अवगत है, यह 8 एक्साबाइट्स (= 8,000,000,000 गीगाबाइट्स) तक की फाइलों को प्रोसेस कर सकता है, आपके ऑपरेटिंग सिस्टम को क्रमशः आपके फाइल सिस्टम को बड़ी फाइल के बारे में भी जानकारी देता है। ( http://www.jonelo.de/java/jacksum/ से लिया गया अंश )

उपयोग उदाहरण:

jacksum -a md5+sha256 -F "#ALGONAME{i} (#FILENAME) = #CHECKSUM{i}" jacksum-testfile

नमूना उत्पादन:

md5 (jacksum-testfile) = d41d8cd98f00b204e9800998ecf8427e
sha256 (jacksum-testfile) = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

उबंटू पर, apt-get install jacksumइसे प्राप्त करने के लिए कमांड चलाएं ।

वैकल्पिक रूप से, स्रोत कोड उपलब्ध हैं


हालांकि यह सही चेकसमों का उत्पादन करता है, यह जावा प्रोग्राम कोरुटिल्स की तुलना में दोगुना धीमा है। यह प्रतिबद्ध संदेश देखें ।
लेकेन्स्टाइन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.