programing

Python에서 파일 해싱

muds 2023. 6. 30. 22:38
반응형

Python에서 파일 해싱

저는 파이썬이 EOF에 읽기를 원하므로 sha1이든 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

TL;DR은 버퍼를 사용하여 많은 양의 메모리를 사용하지 않습니다.

대용량 파일 작업의 메모리 의미를 고려하면 문제의 핵심에 도달할 수 있습니다.우리는 이 나쁜 소년이 2기가바이트 파일을 위해 2기가바이트 램을 뒤지는 것을 원하지 않기 때문에 파스토르피스티가 지적했듯이, 우리는 그 더 큰 파일들을 덩어리로 처리해야 합니다!

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 덩어리로 업데이트하는 것입니다. 우리는 hashlib의 편리한 댄디 업데이트 방법을 따라갑니다.이렇게 하면 한 번에 그 남자를 해시하는 데 필요한 2GB보다 훨씬 적은 메모리를 사용할 수 있습니다!

다음을 사용하여 테스트할 수 있습니다.

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

또한 이 모든 내용은 오른쪽의 링크된 질문에 요약되어 있습니다.Python에서 대용량 파일의 MD5 해시 가져오기


부록!

In general when writing python it helps to get into the habit of following [pep-8][4]. For example, in python variables are typically underscore separated not camelCased. But that's just style and no one really cares about those things except people who have to read bad style... which might be you reading this code years from now.

3.11 이전 버전의 Python을 지원할 필요가 없다면 hashlib을 사용할 수 있습니다.file_message는 다음과 같습니다.

import hashlib

def sha256sum(filename):
    with open(filename, 'rb', buffering=0) as f:
        return hashlib.file_digest(f, 'sha256').hexdigest()

3.11 미만의 Python 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:
        while n := f.readinto(mv):
            h.update(mv[:n])
    return h.hexdigest()

while 루프는 3.8 이전 버전의 Python에서는 사용할 수 없는 할당 표현식을 사용합니다.


이전 Python 3 버전에서는 동일한 버전을 사용할 수 있습니다.

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()

간단히 제안하겠습니다.

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()

여기에 있는 다른 모든 대답들은 너무 복잡해 보입니다.Python은 이미 읽을 때 버퍼링을 수행하고 있습니다(이상적인 방식으로 또는 기본 스토리지에 대한 정보가 더 많은 경우 버퍼링을 구성합니다). 따라서 해시 함수가 이상적이라고 생각하는 부분을 읽는 것이 더 낫습니다. 따라서 해시 함수를 계산하는 데 더 빠르거나 최소한 CPU 집약적이지 않습니다.따라서 버퍼링을 비활성화하고 직접 에뮬레이트하는 대신 Python 버퍼링을 사용하여 데이터 소비자가 이상적으로 생각하는 해시 블록 크기를 제어할 수 있습니다.

POSIX 3(Windows!)를 3, 솔루션가 을합니다.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()

저는 다른 알고리즘으로 큰 파일을 해시할 수 있는 모듈을 프로그래밍했습니다.

pip3 install py_essentials

모듈을 다음과 같이 사용합니다.

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

Python 3.11부터는 파일 읽기를 담당하는 메소드를 사용할 수 있습니다.

import hashlib

with open(inputFile, "rb") as f:
    digest = hashlib.file_digest(f, "sha256")

이를 위해 5-20줄의 코드로 함수를 정의할 필요는 없습니다!pathlibhashlib 라이브러리를 사용하여 시간을 절약할 수 있습니다. 또한 py_essentials도 다른 솔루션이지만 타사는 *****입니다.

from pathlib import Path
import hashlib

filepath = '/path/to/file'
filebytes = Path(filepath).read_bytes()

filehash_sha1 = hashlib.sha1(filebytes)
filehash_md5 = hashlib.md5(filebytes)

print(f'MD5: {filehash_md5}')
print(f'SHA1: {filehash_sha1}')

여기서 몇 가지 변수를 사용하여 단계를 보여드렸습니다. 이 단계를 피하는 방법을 알고 있습니다.

아래 기능에 대해 어떻게 생각하십니까?

from pathlib import Path
import hashlib


def compute_filehash(filepath: str, hashtype: str) -> str:
    """Computes the requested hash for the given file.

    Args:
        filepath: The path to the file to compute the hash for.
        hashtype: The hash type to compute.

          Available hash types:
            md5, sha1, sha224, sha256, sha384, sha512, sha3_224,
            sha3_256, sha3_384, sha3_512, shake_128, shake_256

    Returns:
        A string that represents the hash.
    
    Raises:
        ValueError: If the hash type is not supported.
    """
    if hashtype not in ['md5', 'sha1', 'sha224', 'sha256', 'sha384',
                        'sha512', 'sha3_224', 'sha3_256', 'sha3_384',
                        'sha3_512', 'shake_128', 'shake_256']:
        raise ValueError(f'Hash type {hashtype} is not supported.')
    
    return getattr(hashlib, hashtype)(
        Path(filepath).read_bytes()).hexdigest()

FWIW, 저는 maxschlepzig의 답변과 동일한 메모리 및 성능 특성을 가지지만 IMO가 더 읽기 쉬운 이 버전을 선호합니다.

import hashlib

def sha256sum(filename, bufsize=128 * 1024):
    h = hashlib.sha256()
    buffer = bytearray(bufsize)
    # using a memoryview so that we can slice the buffer without copying it
    buffer_view = memoryview(buffer)
    with open(filename, 'rb', buffering=0) as f:
        while True:
            n = f.readinto(buffer_view)
            if not n:
                break
            h.update(buffer_view[:n])
    return h.hexdigest()
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)

언급URL : https://stackoverflow.com/questions/22058048/hashing-a-file-in-python

반응형