سؤال

ومع الثعبان 2.7 التعليمة البرمجية التالية يحسب hexdigest MD5 من محتويات الملف.

و(تحرير: حسنا، ليست حقا كما أظهرت الإجابات، أنا مجرد التفكير بذلك)

.
import hashlib

def md5sum(filename):
    f = open(filename, mode='rb')
    d = hashlib.md5()
    for buf in f.read(128):
        d.update(buf)
    return d.hexdigest()

والآن إذا قمت بتشغيل هذا الرمز باستخدام python3 أنه رفع استثناء TypeError:

    d.update(buf)
TypeError: object supporting the buffer API required

وأنا أحسب أن أتمكن من جعل هذا المدى الرمز مع كل من python2 وpython3 يتغير إلى:

def md5sum(filename):
    f = open(filename, mode='r')
    d = hashlib.md5()
    for buf in f.read(128):
        d.update(buf.encode())
    return d.hexdigest()

والآن أنا لا أزال أتساءل لماذا توقفت رمز الأصلي العمل. ويبدو أن عند فتح ملف باستخدام الوضع الثنائي معدل فإنها ترجع الأعداد الصحيحة بدلا من سلاسل المشفرة كما بايت (وأقول ذلك لأن عوائد نوع (BUF) الباحث). ويفسر هذا السلوك في مكان ما؟

هل كانت مفيدة؟

المحلول

وأعتقد أنك أراد حلقة لإجراء المكالمات المتتالية إلى f.read(128). التي يمكن أن يتم ذلك باستخدام ايتر () و <م> functools.partial () :

import hashlib
from functools import partial

def md5sum(filename):
    with open(filename, mode='rb') as f:
        d = hashlib.md5()
        for buf in iter(partial(f.read, 128), b''):
            d.update(buf)
    return d.hexdigest()

print(md5sum('utils.py'))

نصائح أخرى

for buf in f.read(128):
  d.update(buf)

و.. بتحديث التجزئة بالتتابع مع كل من أول 128 <م> بايت قيم الملف. منذ بالتكرار على bytes تنتج الأجسام int، يمكنك الحصول على المكالمات التالية التي تسبب الخطأ الذي واجه في Python3.

d.update(97)
d.update(98)
d.update(99)
d.update(100)

والذي هو ليس ما تريد.

وبدلا من ذلك، تريد:

def md5sum(filename):
  with open(filename, mode='rb') as f:
    d = hashlib.md5()
    while True:
      buf = f.read(4096) # 128 is smaller than the typical filesystem block
      if not buf:
        break
      d.update(buf)
    return d.hexdigest()

وأخيرا غيرت قانون بلدي إلى الإصدار أدناه (أن أجد من السهل أن نفهم) بعد طرح السؤال. ولكنني لن ربما تغييره إلى الإصدار الذي اقترحه ريمون Hetting unsing functools.partial.

import hashlib

def chunks(filename, chunksize):
    f = open(filename, mode='rb')
    buf = "Let's go"
    while len(buf):
        buf = f.read(chunksize)
        yield buf

def md5sum(filename):
    d = hashlib.md5()
    for buf in chunks(filename, 128):
        d.update(buf)
    return d.hexdigest()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top