पायथन में एक फ़ाइल को हैशिंग


100

मैं अजगर को ईओएफ में पढ़ना चाहता हूं ताकि मुझे एक उपयुक्त हैश मिल सके, चाहे वह श 1 या md5 हो। कृपया मदद करे। यह है, जो कि अभी तक मेरे पास है:

import hashlib

inputFile = raw_input("Enter the name of the file:")
openedFile = open(inputFile)
readFile = openedFile.read()

md5Hash = hashlib.md5(readFile)
md5Hashed = md5Hash.hexdigest()

sha1Hash = hashlib.sha1(readFile)
sha1Hashed = sha1Hash.hexdigest()

print "File Name: %s" % inputFile
print "MD5: %r" % md5Hashed
print "SHA1: %r" % sha1Hashed

6
और क्या समस्या है?
isedev

1
मैं चाहता हूं कि यह एक फाइल हैश कर सके। मुझे यह पढ़ने की आवश्यकता है कि ईओएफ तक, फ़ाइल का आकार जो भी हो।
user3358300

3
यह वही है जो file.read()पूरी फाइल को पढ़ता है।
isedev

read()विधि के लिए प्रलेखन कहते हैं?
इग्नासियो वाज़केज़-अब्राम्स

आपको "हैशिंग क्या है?" के माध्यम से जाना चाहिए।
शरीफ मामून

जवाबों:


140

टीएल; डीआर बफ़र्स का उपयोग स्मृति के टन का उपयोग नहीं करने के लिए करते हैं।

हम आपकी समस्या की जड़ तक पहुँचते हैं, मुझे विश्वास है, जब हम बहुत बड़ी फ़ाइलों के साथ काम करने के मेमोरी निहितार्थ पर विचार करते हैं । हम इस बुरे लड़के को 2 गीगाबाइट फ़ाइल के लिए 2 गिग्स के माध्यम से मंथन करने के लिए नहीं चाहते हैं, जैसा कि pasztorpisti बताते हैं, हम उन बड़ी फाइलों के साथ विखंडू में सौदा करते हैं!

import sys
import hashlib

# BUF_SIZE is totally arbitrary, change for your app!
BUF_SIZE = 65536  # lets read stuff in 64kb chunks!

md5 = hashlib.md5()
sha1 = hashlib.sha1()

with open(sys.argv[1], 'rb') as f:
    while True:
        data = f.read(BUF_SIZE)
        if not data:
            break
        md5.update(data)
        sha1.update(data)

print("MD5: {0}".format(md5.hexdigest()))
print("SHA1: {0}".format(sha1.hexdigest()))

हमने जो किया है, हम 64kb विखंडू में इस बुरे लड़के के अपने हैश को अपडेट कर रहे हैं क्योंकि हम हैशलीब के आसान डंडी अपडेट विधि के साथ चलते हैं । इस तरह हम 2gb की तुलना में बहुत कम मेमोरी का उपयोग करते हैं यह आदमी को एक बार में हैश में ले जाएगा!

आप इसके साथ परीक्षण कर सकते हैं:

$ mkfile 2g bigfile
$ python hashes.py bigfile
MD5: a981130cf2b7e09f4686dc273cf7187e
SHA1: 91d50642dd930e9542c39d36f0516d45f4e1af0d
$ md5 bigfile
MD5 (bigfile) = a981130cf2b7e09f4686dc273cf7187e
$ shasum bigfile
91d50642dd930e9542c39d36f0516d45f4e1af0d  bigfile

उम्मीद है की वो मदद करदे!

इसके अलावा यह सब दाहिने हाथ से जुड़े प्रश्न में उल्लिखित है: पायथन में बड़ी फ़ाइलों की MD5 हैश प्राप्त करें


परिशिष्ट!

सामान्य रूप से अजगर लिखते समय यह पेप -8 का अनुसरण करने की आदत में मदद करता है । उदाहरण के लिए, अजगर वेरिएबल्स में आमतौर पर अंडरस्कोर को अलग किया जाता है जो ऊंट नहीं होता है। लेकिन यह सिर्फ शैली है और कोई भी वास्तव में उन चीजों के बारे में परवाह नहीं करता है, सिवाय उन लोगों के बारे में जिन्हें बुरी शैली को पढ़ना है ... जो अब से शायद आप इस कोड को पढ़ रहे हैं।


@ranman नमस्कार, मैं {0} "प्राप्त नहीं कर सका। प्रारूप (sha1.hexdigest ()) भाग। हम सिर्फ sha1.hexdigest () का उपयोग करने के बजाय इसका उपयोग क्यों करते हैं?
Belial

@ काम क्या काम नहीं कर रहा था? मैं मुख्य रूप से सिर्फ दो हैश के बीच अंतर करने के लिए उपयोग कर रहा था ...
रान्डेल हंट

@ranman सब कुछ काम कर रहा है, मैंने अभी कभी इसका इस्तेमाल नहीं किया और इसे साहित्य में नहीं देखा। "{0}"। प्रारूप () ... मेरे लिए अज्ञात। :)
बेलियल

1
मुझे कैसे चुनना चाहिए BUF_SIZE?
मार्टिन थोमा

1
यह shasumबायनेरिज़ के समान परिणाम उत्पन्न नहीं करता है । नीचे सूचीबद्ध अन्य उत्तर (मेमोरीव्यू का उपयोग करने वाला) अन्य हैशिंग टूल्स के साथ संगत है।
१ed:५३ पर tedivm

61

किसी फ़ाइल के हैश मान के सही और कुशल गणना के लिए (पायथन 3 में):

  • 'b'चरित्र एन्कोडिंग और लाइन-एंड रूपांतरण रूपांतरण समस्याओं से बचने के लिए फ़ाइल को बाइनरी मोड में खोलें (यानी फिल्मकोड में जोड़ें )।
  • पूरी फ़ाइल को मेमोरी में न पढ़ें, क्योंकि यह मेमोरी की बर्बादी है। इसके बजाय, क्रमिक रूप से इसे ब्लॉक द्वारा पढ़ें और प्रत्येक ब्लॉक के लिए हैश को अपडेट करें।
  • डबल बफ़रिंग को हटा दें, अर्थात बफ़र्ड IO का उपयोग न करें, क्योंकि हम पहले से ही एक इष्टतम ब्लॉक आकार का उपयोग करते हैं।
  • readinto()बफर मंथन से बचने के लिए उपयोग करें ।

उदाहरण:

import hashlib

def sha256sum(filename):
    h  = hashlib.sha256()
    b  = bytearray(128*1024)
    mv = memoryview(b)
    with open(filename, 'rb', buffering=0) as f:
        for n in iter(lambda : f.readinto(mv), 0):
            h.update(mv[:n])
    return h.hexdigest()

2
आपको कैसे पता चलेगा कि एक इष्टतम ब्लॉक आकार क्या है?
मैटर

1
@ मैटर, एक निचला बाउंड फिजिकल ब्लॉक (पारंपरिक रूप से 512 बाइट्स या नए डिस्क के साथ 4KiB) और सिस्टम पेज का आकार (कई सिस्टम पर 4KiB, अन्य सामान्य विकल्प: 8KiB और 64 KiB) की अधिकतम सीमा है। फिर आप मूल रूप से कुछ बेंचमार्किंग और / या प्रकाशित बेंचमार्क परिणामों और संबंधित कार्यों को देखते हैं (उदाहरण के लिए वर्तमान rsync / GNU cp / ... का उपयोग करें)।
अधिकतम २० मिनट

resource.getpagesizeअगर हम इसे कुछ गतिशील रूप से अनुकूलित करने का प्रयास करना चाहते हैं, तो यहां कोई फायदा नहीं होगा ? और किस बारे में mmap?
jpmc26

@ jpmc26, getpagesize () यहां उपयोगी नहीं है - सामान्य मूल्य 4 KiB या 8 KiB हैं, उस सीमा में कुछ, यानी 128 KiB - 128 KiB की तुलना में बहुत छोटा आम तौर पर एक अच्छा विकल्प है। mmap हमारे उपयोग के मामले में बहुत मदद नहीं करता है क्योंकि हम क्रमिक रूप से आगे से पीछे तक पूरी फ़ाइल पढ़ते हैं। मिमीप के फायदे हैं जब एक्सेस पैटर्न अधिक यादृच्छिक-पहुंच है, जैसे यदि पृष्ठों को एक से अधिक बार एक्सेस किया जाता है और / या अगर यह mmap बफर प्रबंधन को सरल करता है।
मैक्सक्लेपजिग

3
मैंने लगभग 116GB और sha1sum एल्गोरिथ्म की एक फ़ाइल के साथ (1) @ रैंडल हंट और (2) तुम्हारा (इस क्रम में, फ़ाइल कैश के कारण महत्वपूर्ण है) दोनों के समाधान को बेंचमार्क किया। समाधान 1 को 20 * 4096 (PAGE_SIZE) के बफर का उपयोग करने के लिए संशोधित किया गया था और बफरिंग पैरामीटर को 0. समाधान 2 में सेट किया गया था, केवल एल्गोरिथ्म को संशोधित किया गया था (sha256 -> sha1)। परिणाम: (1) 3m37.137s (2) 3m30.003s। द्विआधारी मोड में देशी शा 1sum: 3m31.395s
बायोइन्फोरमैटिक्स

18

मैं बस प्रस्ताव देना चाहता हूँ:

def get_digest(file_path):
    h = hashlib.sha256()

    with open(file_path, 'rb') as file:
        while True:
            # Reading is buffered, so we can read smaller chunks.
            chunk = file.read(h.block_size)
            if not chunk:
                break
            h.update(chunk)

    return h.hexdigest()

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


सही उत्तर, लेकिन यह अच्छा होगा, यदि आप संबंधित डॉक के साथ अपने बयान वापस करेंगे: पायथन 3 - खुला () और पायथन 2 - खुला () । यहां तक ​​कि दोनों के बीच अंतर को ध्यान में रखें, पायथन 3 का दृष्टिकोण अधिक परिष्कृत है। फिर भी, मैंने वास्तव में उपभोक्ता-केंद्रित दृष्टिकोण की सराहना की है!
मूरमेल

hash.block_size'हैश एल्गोरिथ्म के आंतरिक ब्लॉक आकार' के रूप में प्रलेखित है। हाशिब को यह आदर्श नहीं लगता । पैकेज डॉक्यूमेंटेशन में कुछ भी नहीं बताता है कि आकार इनपुट update()पसंद करता है hash.block_size। यदि आप इसे इस तरह कहते हैं तो यह कम सीपीयू का उपयोग नहीं करता है। आपकी file.read()कॉल कई अनावश्यक ऑब्जेक्ट क्रिएशन और फ़ाइल बफ़र से लेकर आपके नए चंक बाइट्स ऑब्जेक्ट तक ले जाती है।
मैक्सक्लेपज़िग

हैक्स अपने राज्य को block_sizeविखंडू में अद्यतन करते हैं । यदि आप उन्हें उन खंडों में प्रदान नहीं कर रहे हैं, तो उन्हें बफर करना होगा और पर्याप्त डेटा के आंतरिक रूप से दिए गए डेटा को प्रदर्शित करने के लिए इंतजार करना होगा। तो, आप बस इसे बाहर की तरफ संभाल सकते हैं और फिर आंतरिक रूप से क्या होता है, इसे सरल बनाते हैं। मुझे यह आदर्श लगता है। उदाहरण के लिए देखें: stackoverflow.com/a/51335622/252025
Mitar

block_sizeकिसी भी उपयोगी पढ़ने आकार की तुलना में काफी कम है। इसके अलावा, किसी भी उपयोगी ब्लॉक और रीड साइज दो की शक्तियां हैं। इस प्रकार, रीड साइज संभवतः पिछले एक को छोड़कर सभी रीड्स के लिए ब्लॉक साइज से विभाज्य है। उदाहरण के लिए, Sha256 ब्लॉक का आकार 64 बाइट्स है। इसका मतलब है कि update()किसी भी बफरिंग के बिना किसी भी इनपुट को सीधे प्रोसेस करने में सक्षम है block_size। इस प्रकार, केवल तभी यदि पिछले रीड को ब्लॉक आकार से विभाज्य नहीं किया गया है, इसे 63 बाइट्स तक बफर करना है, एक बार। इसलिए, आपकी अंतिम टिप्पणी गलत है और आपके द्वारा अपने उत्तर में किए जा रहे दावों का समर्थन नहीं करती है।
मैकशलेपजिग

मुद्दा यह है कि किसी को बफरिंग का अनुकूलन करने की आवश्यकता नहीं है क्योंकि यह पहले से ही पढ़ते समय पायथन द्वारा किया जाता है। तो आपको बस उस मौजूदा बफ़र पर हैशिंग के दौरान आप जो लूपिंग करना चाहते हैं, उसका फैसला करना है।
Mitar

5

मैंने एक मॉड्यूल को प्रोग्राम किया है जो विभिन्न एल्गोरिदम के साथ बड़ी फ़ाइलों को हैश करने में सक्षम है।

pip3 install py_essentials

इस तरह मॉड्यूल का उपयोग करें:

from py_essentials import hashing as hs
hash = hs.fileChecksum("path/to/the/file.txt", "sha256")

5

यहाँ एक पायथन 3, POSIX समाधान (विंडोज नहीं है!) जो mmapऑब्जेक्ट को मेमोरी में मैप करने के लिए उपयोग करता है।

import hashlib
import mmap

def sha256sum(filename):
    h  = hashlib.sha256()
    with open(filename, 'rb') as f:
        with mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) as mm:
            h.update(mm)
    return h.hexdigest()

भोला सवाल ... mmapइस परिदृश्य में उपयोग करने का क्या फायदा है?
जोनाथन बी।

1
@JonathanB। अधिकांश विधियाँ अनावश्यक रूप bytesसे स्मृति में वस्तुओं का निर्माण करती हैं, और readबहुत अधिक या बहुत कम बार बुलाती हैं। यह फ़ाइल को सीधे वर्चुअल मेमोरी में मैप करेगा, और वहां से हैश करेगा - ऑपरेटिंग सिस्टम बफर कैशे से सीधे फाइल कंटेंट को रीडिंग प्रोसेस में मैप कर सकता है। यह इस में एक महत्वपूर्ण पहलू से तेजी से हो सकता है इसका मतलब यह एक
अंटी Haapala

@JonathanB। मैंने परीक्षण किया और अंतर इस मामले में उतना महत्वपूर्ण नहीं है , हम बात कर रहे हैं ~ भोले तरीके पर ~ 15%।
अंती हापाला

-2
import hashlib
user = input("Enter ")
h = hashlib.md5(user.encode())
h2 = h.hexdigest()
with open("encrypted.txt","w") as e:
    print(h2,file=e)


with open("encrypted.txt","r") as e:
    p = e.readline().strip()
    print(p)

2
आप मूल रूप से ऐसा कर रहे हैं echo $USER_INPUT | md5sum > encrypted.txt && cat encrypted.txtजो फाइलों के हैशिंग के साथ नहीं है, खासकर बड़े लोगों के साथ नहीं।
मूरमेल

1
हैशिंग! = एनक्रिप्टिंग
Bugmenot123
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.