Portable App zur Berechnung eines (wählbaren) Hashes für eine ausgewählte Datei?

Seltsamerweise kann ich keine portable Anwendung finden, um einen bestimmten Hash (Typ wie SHA256, SHA512, Whirlpool, SHA3?) Für eine ausgewählte Datei zu berechnen! Das ist alles, was ich gefunden habe:

  1. RapidCRCUnicodePortable - es hat ein sehr benutzerunfreundliches Verhalten. Was sehe ich? Ich öffne diese App, klicke auf die Schaltfläche "Dateien öffnen" und wähle meine Datei aus. Ich sehe den Dateinamen in der Liste und eine seltsame Meldung rechts: "Kein Hash gefunden". Okay, ich klicke auf die Schaltfläche "SHA256-Datei" und sehe diese Meldung: "Sie müssen zuerst die SHA256-Prüfsummen berechnen. Klicken Sie auf OK, um das jetzt zu tun." Ich klicke auf OK. Der Dateiname wird jetzt in der Liste mit dem gleichen „Kein Hash gefunden“-Text auf der rechten Seite dupliziert, aber jetzt – Glückwunsch ! – Endlich kann ich den gefundenen SHA256-Hash in die Zwischenablage kopieren. Und seltsamerweise stürzt diese App in meinem System ab, wenn ich Dateien aus der Liste entferne. Ich kann nicht verstehen, wie dieser Fehler existieren darf. Es lässt mich denken, dass diese Software instabil ist.
  2. ChecksumControlPortable dient nur zum Erstellen von SFV/MD5-Dateien. Übrigens kann es nicht einmal eine separate Datei über den Explorer auswählen, es verwendet eine Drag-and-Drop-Schnittstelle, aber ich hasse diese Art von Schnittstelle. Drag&Drop verwende ich nie.
  3. HashGenerator verschwendet viel Zeit und CPU-Zyklen, um alle Arten von Hashes auf einmal zu berechnen. Dies macht diese App beim Umgang mit großen Dateien äußerst benutzerunfreundlich.

Es gibt Multihasher , aber es unterstützt einige wichtige Hash-Typen wie SHA-3 und Whirlpool nicht.
HashTab hat alles, was ich brauche, aber ... schade! Es ist eine installierbare DLL für die Systemintegration ohne portable Anwendung.
Eigentlich bin ich etwas geschockt von dieser Situation. Ich hätte nie erwartet, dass ich nicht in der Lage sein würde, die geeignete Software für ein so häufiges Problem zu finden.

WinMD5 berechnet nur MD5.
HashMyFiles berechnet nur CRC32, MD5 und SHA1
Für Windows? Wenn ja, ist möglicherweise .NET erforderlich? Welche Hashes sollte es mindestens unterstützen?
@wb9688: "Kann es .NET erfordern?" Nein. .NET-Abhängigkeit bedeutet, dass der Benutzer gezwungen ist, das Framework zu installieren , bevor er die App verwendet. Dies ist nicht immer möglich. Und soweit ich weiß, gibt es kein portables .NET . "Welche Hashes sollte es mindestens unterstützen?" SHA-2 ist erforderlich, nehme ich an. SHA-3 und Whirlpool wären schön zu haben, denke ich.

Antworten (2)

Vor einiger Zeit habe ich ein kleines Befehlszeilenprogramm für mich erstellt. Laden Sie es herunter, wenn Sie es nützlich finden.

Das Programm wurde noch nie zuvor veröffentlicht (oder signiert), sodass es möglicherweise als Malware erkannt wird (zumindest sagt VirusTotal das).

Es ist in Python 3 geschrieben. Dies ist die Quelle:

# -*- coding: utf-8 -*-

import os.path
import pprint
import time
import json
import sys
import re
import hashlib
import zlib
import sha3 # This adds sha_3 functions to the hashlib module, install with 'pip install pysha3'

class crc32(object):
    name = 'crc32'
    digest_size = 4
    block_size = 1

    def __init__(self, arg=''):
        arg = arg.encode()
        self.__digest = 0
        self.update(arg)

    def copy(self):
        copy = super(self.__class__, self).__new__(__class__)
        copy.__digest = self.__digest
        return copy

    def digest(self):
        return self.__digest

    def hexdigest(self):
        return '{:08x}'.format(self.__digest)

    def update(self, arg):
        self.__digest = zlib.crc32(arg, self.__digest) & 0xffffffff

hashlib.crc32 = crc32

def md4File(path, block_size=256*128):
    md4 = hashlib.new("md4")
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            md4.update(chunk)
    return md4.hexdigest()

def md5File(path, block_size=256*128):
    md5 = hashlib.md5()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            md5.update(chunk)
    return md5.hexdigest()

def sha1File(path, block_size=256*128):
    sha1 = hashlib.sha1()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha1.update(chunk)
    return sha1.hexdigest()

def crc32File(path, block_size=256*128):
    crc32 = hashlib.crc32()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            crc32.update(chunk)
    return crc32.hexdigest()

def sha224File(path, block_size=256*128):
    sha224 = hashlib.sha224()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha224.update(chunk)
    return sha224.hexdigest()

def sha256File(path, block_size=256*128):
    sha256 = hashlib.sha224()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha256.update(chunk)
    return sha256.hexdigest()

def sha384File(path, block_size=256*128):
    sha384 = hashlib.sha384()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha384.update(chunk)
    return sha384.hexdigest()

def sha512File(path, block_size=256*128):
    sha512 = hashlib.sha512()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha512.update(chunk)
    return sha512.hexdigest()

def ripemd160File(path, block_size=256*128):
    rmd160 = hashlib.new("ripemd160")
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            rmd160.update(chunk)
    return rmd160.hexdigest()

def dsaFile(path, block_size=256*128):
    dsa = hashlib.new("dsa")
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            dsa.update(chunk)
    return dsa.hexdigest()

def whirlpoolFile(path, block_size=256*128):
    wrp = hashlib.new("whirlpool")
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            wrp.update(chunk)
    return wrp.hexdigest()

def sha3_224File(path, block_size=256*128):
    sha3_224 = hashlib.sha3_224()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha3_224.update(chunk)
    return sha3_224.hexdigest()

def sha3_256File(path, block_size=256*128):
    sha3_256 = hashlib.sha3_256()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha3_256.update(chunk)
    return sha3_256.hexdigest()

def sha3_384File(path, block_size=256*128):
    sha3_384 = hashlib.sha3_384()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha3_384.update(chunk)
    return sha3_384.hexdigest()

def sha3_512File(path, block_size=256*128):
    sha3_512 = hashlib.sha3_512()
    with open(path,'rb') as f: 
        for chunk in iter(lambda: f.read(block_size), b''): 
            sha3_512.update(chunk)
    return sha3_512.hexdigest()


def getJson(results):
    jdump = json.dumps(results, ensure_ascii=False)
    return re.sub('[^\s!-~]', '?', jdump)

def getString(results):
    text = ""
    for i in results:
        text += "File: " + i + "\n"

        for j in results[i]:
            text += j[0] + ": " + j[1] + "\n"

        text += "\n"

    return re.sub('[^\s!-~]', '?', text[:-2])


def showHelp(name):
    nameT = name.replace("\\","/").split("/")[-1]
    helpText = """
//////////////////////
/ File/Folder hasher /
//////////////////////

Usage: %s  path [-md4]       [-md5]
            [-sha1]      [-crc32]
            [-sha224]    [-sha256]
            [-sha384]    [-sha512]
            [-ripemd160] [-whirlpool]
            [-sha3_224]  [-sha3_256]
            [-sha3_384]  [-sha3_512]

            [-all]
            [-file <file name>]
            [-json]

Options:
    path    Path to file or directory to hash

    -all    Use all hash algorithms.
    -file   Save hash report to a text file
    -json   Format output in json

Hash algorithm options:
    -md4    
    -md5
    -sha1
    -crc32
    -sha224
    -sha256
    -sha384
    -sha512
    -ripemd160
    -whirlpool
    -sha3_224
    -sha3_256
    -sha3_384
    -sha3_512
"""
    print(helpText % nameT)

def main():
    args = sys.argv

    if len(args) < 3:
        print("Not enough arguments!")
        showHelp(args[0])
        sys.exit(1)

    allowed = [
    "-file",
    "-all",
    "-md4",
    "-md5",
    "-sha1",
    "-crc32",
    "-sha224",
    "-sha256",
    "-sha384",
    "-sha512",
    "-ripemd160",
    "-whirlpool",
    "-json",
    "-raw",
    "-sha3_224",
    "-sha3_256",
    "-sha3_384",
    "-sha3_512",
    ]

    hashes = [
    "-md4",
    "-md5",
    "-sha1",
    "-crc32",
    "-sha224",
    "-sha256",
    "-sha384",
    "-sha512",
    "-ripemd160",
    "-whirlpool",
    "-sha3_224",
    "-sha3_256",
    "-sha3_384",
    "-sha3_512",
    ]

    dataContain = [
    "-file",
    ]

    b = 2
    for i in args[b:]:
        if args.count(i) > 1:
            print("Repeating options: " + i)
            showHelp(args[0])
            sys.exit(1)

        if not i in allowed and args[b-1] not in dataContain:
            print("Invalid option: " + i)
            print(args[b+1])
            showHelp(args[0])
            sys.exit(1)

        b += 1
    else:
        if args[-1] in dataContain:
            print("'%s' option must have a file path next to it." % i)
            showHelp(args[0])
            sys.exit(1) 

    for i in args[2:]:
        if i in hashes + ["-all"]:
            break

    else:
        print("No hashes specified.")
        showHelp(args[0])
        sys.exit(1)         

    collisions = {
    "-all" : ["-md4", "-md5", "-sha1", 
              "-crc32", "-sha224", "-sha256", 
              "-sha384", "-sha512", "-ripemd160", 
              "-whirlpool", "-sha3_224", "-sha3_256", 
              "-sha3_384", "-sha3_512",]
    }

    for i in collisions:
        if i in args:
            for j in collisions[i]:
                if j in args:
                    print("Colliding options. (" + i + " and " + j + ")")
                    showHelp(args[0])
                    sys.exit(1)

    fileName = args[1]
    fileNameT = fileName.replace("\\", "/").split("/")[-1]
    if os.path.isfile(fileName):
        ftype = "file"

    elif os.path.isdir(fileName):
        ftype = "directory"

    else:
        print("File or directory does not exits or you don't have permission to read it.")
        showHelp(args[0])
        sys.exit(1) 

    funcTable = {
    "-md4"        : ("MD4", md4File),
    "-md5"        : ("MD5", md5File),
    "-sha1"       : ("SHA1", sha1File),
    "-crc32"      : ("CRC32", crc32File),
    "-sha224"     : ("SHA224", sha224File),
    "-sha256"     : ("SHA256", sha256File),
    "-sha384"     : ("SHA384", sha384File),
    "-sha512"     : ("SHA512", sha512File),
    "-ripemd160"  : ("Ripemd160", ripemd160File),
    "-whirlpool"  : ("Whirlpool", whirlpoolFile),
    "-sha3_224"   : ("SHA3-224", sha3_224File),
    "-sha3_256"   : ("SHA3-256", sha3_256File),
    "-sha3_384"   : ("SHA3-384", sha3_384File),
    "-sha3_512"   : ("SHA3-512", sha3_512File),
    }
    funcList = []

    if "-all" in args:
        for i in hashes:
            funcList.append(funcTable[i])
    else:
        for i in hashes:
            if i in args:
                funcList.append(funcTable[i])

    try:
        if ftype == "file":
            print("Hashing...\n")

            results = {}
            results[fileNameT] = []
            st = time.time()
            try:
                for function in funcList:
                    hash = function[1](fileName)
                    results[fileNameT].append([function[0], hash])

            except KeyboardInterrupt:
                print("Hashing canceled.")
                sys.exit(2)

            except PermissionError:
                print("You don't have permission to access the file.")
                showHelp(args[0])
                sys.exit(2)         

            et = time.time()

            if "-json" in args:
                strResults = getJson(results)

            elif "-raw" in args:
                strResults = results

            else:
                strResults = getString(results)

            if "-file" in args:
                print("Writing file...")
                f = open(args[args.index("-file") + 1], "w")
                f.write(strResults)
                f.close()
                print("File saved sucessfully in %s seconds." % str("{0:.2f}".format(et-st)))

            else:
                print(strResults)
                print("\nCalculated in %s seconds." % str("{0:.2f}".format(et-st)))

            sys.exit(0)

        else:
            filenum = 0
            print("Scanning files...")

            st = time.time()
            try:
                for subdir, dirs, files in os.walk(fileName):
                    for file in files:
                        filenum += 1        

            except KeyboardInterrupt:
                print("Files not scanned. Progress cannot be tracked.")
                filenum = -1

            if filenum == 0:
                print("Directory is empty or you don't have permission to read it.")
                showHelp(args[0])
                sys.exit(1)

            print("Number of files: " + str(filenum))
            print("Hashing...\n")

            results = {}

            onfile = 1
            passed = 0
            try:
                if filenum == -1:
                    print(" |     Hashing...     | ???%", end="\r")

                for subdir, dirs, files in os.walk(fileName):
                    for file in files:
                        results[os.path.join(subdir, file)] = []

                        if filenum != -1:
                            perc = onfile/filenum
                            percnum = "{0:.2f}".format(perc*100)
                            toprint = " |" + ("#" * int((20*perc))) + " " * int(20-int(20*perc))  + "| " + percnum + "%"

                            print(toprint, end="\r")

                        for function in funcList:
                            try:
                                try:
                                    hash = function[1](os.path.join(subdir, file))
                                    results[os.path.join(subdir, file)].append([function[0], hash])

                                except PermissionError:
                                    results[os.path.join(subdir, file)].append(["Error", "Access denied"])
                                    passed += 1

                                except FileNotFoundError:
                                    results[os.path.join(subdir, file)].append(["Error", "File not found"])
                                    passed += 1
                            except Exception as e:
                                results[os.path.join(subdir, file)].append(["Error", str(e)])
                                passed += 1

                        onfile += 1

                else:
                    print(" |####################| 100%       \n")



            except KeyboardInterrupt:
                print("Hashing canceled.                 ")
                sys.exit(2)

            et = time.time()
            print("Passed %s files" % str(passed))

            if "-json" in args:
                strResults = getJson(results)

            elif "-raw" in args:
                strResults = results

            else:
                strResults = getString(results)

            if "-file" in args:
                print("Writing file...")
                f = open(args[args.index("-file") + 1], "wb")
                f.write(strResults.encode())
                f.close()
                print("\nFile saved sucessfully in %s seconds." % str("{0:.2f}".format(et-st)))

            else:
                print(strResults)
                print("\nCalculated in %s seconds." % str("{0:.2f}".format(et-st)))

            sys.exit(0)

    except MemoryError:
        print("Maximum memory reached. Please consider using an x64 version of the program and upgrading your RAM.\n")

if __name__ == "__main__":
    main()

Es kann eine Datei oder einen Ordner mit diesen Algorithmen hashen:

  • md4

  • md5

  • sha1
  • crc32
  • sha224
  • sha256
  • sha384
  • sha512
  • reifemd160
  • Whirlpool
  • sha3_224
  • sha3_256
  • sha3_384
  • sha3_512

  • Sie können die gehashten Werte auch in einer Datei speichern oder sie zum einfachen Analysieren mit json formatieren.

Das Schöne daran ist, dass Sie ganz einfach eine .bat-Datei erstellen können, um sie zu automatisieren.

Wenn Sie dieses Programm tatsächlich brauchen, aber Ihrem Antivirus mehr vertrauen als mir, kompilieren Sie die obige Quelle mit pyinstaller .

  1. Installieren Sie Python 3 (achten Sie auf 32-Bit/64-Bit-Versionen)
  2. Pyinstaller installieren:pip install pyinstaller
  3. Speichern Sie die Quelle in einer Datei namens hasher.py
  4. Führen Sie den Befehl aus: pyinstaller hasher.py4.5 Führen Sie optional Folgendes aus: pyinstaller hasher.py --onefilewenn Sie nur eine ausführbare Datei wünschen
  5. Profitieren

Beachten Sie, dass die Kompatibilität der kompilierten Exe nicht getestet wurde, da ich keine Zeit habe.

Klicken Sie mich zum Download an.

rhash ist ein cmdline-Tool, das einzelne Hashes berechnen kann.

Sie können mein Shellex.bat-Skript verwenden , um einen Eintrag im Kontextmenü des Explorers hinzuzufügen, der den Hash in einem Konsolenfenster anzeigt.

Beispielsweise wird dadurch jeder Datei ein „CRC32“-Befehl hinzugefügt (einfügen und aus einer Batch-Datei ausführen):

call shellex * CRC32 ""%~d0\PortableApps\ConEmu\ConEmu.exe" /cmd "%PROGRAMFILES%\Rhash\rhash.exe" -C --simple ""%%%%1""" 

Eine weitere Option mit Certuil ist hier .

Übrigens, für kleine Dateien bevorzuge ich eigentlich HashMyFiles wegen der benutzerfreundlicheren GUI.