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:
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.
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
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 .
pip install pyinstaller
pyinstaller hasher.py
4.5 Führen Sie optional Folgendes aus: pyinstaller hasher.py --onefile
wenn Sie nur eine ausführbare Datei wünschenBeachten Sie, dass die Kompatibilität der kompilierten Exe nicht getestet wurde, da ich keine Zeit habe.
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.
Thomas Weller
Thomas Weller
wb9688
lyrisch geil