RapidCRCUnicodePortable-它具有非常用户不友好的行为。我看到了什么?我打开此应用程序,单击“打开文件”按钮,然后选择我的文件。我在列表中看到文件名,并在右侧看到一条奇怪的消息:“未找到哈希”。好的,我单击“ SHA256文件”按钮,然后看到以下消息:“您必须先计算sha256校验和。单击确定立即执行。”我单击确定。现在,文件名在列表中重复了,并在右侧带有相同的“未找到哈希”文本,但是现在–恭喜! –我终于可以将找到的SHA256哈希复制到剪贴板。奇怪的是,当我从列表中删除文件时,此应用程序在系统中崩溃。我不明白这个错误是怎么存在的。它使我认为该软件不稳定。
ChecksumControlPortable仅用于创建SFV / MD5文件。顺便说一句,它甚至无法通过资源管理器选择单独的文件,它使用拖放界面,但是我讨厌这种界面。我从不使用拖放。
HashGenerator浪费大量时间,CPU周期一次计算所有类型的哈希。处理大型文件时,它会使该应用程序变得极为用户不友好。
有Multihasher,但是它不支持某些重要的哈希类型,例如SHA-3和Whirlpool。HashTab满足了我的所有需求,但是...真可惜!它是可安装的dll,无需便携式应用程序即可进行系统集成。
实际上,我对这种情况感到有些震惊。我从没想到过我无法找到合适的软件来解决这种常见问题。
#1 楼
前一段时间,我为自己制作了一个命令行实用程序。如果发现有用,请下载该软件。该程序以前从未发布过(或未签名),因此可能被检测为恶意软件(至少VirusTotal这样说)。
它是用Python 3编写。来源:
# -*- 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()
它可以使用以下算法对文件或文件夹进行哈希处理:
md4
md5
sha1
crc32
sha224
sha384
sha512
ripemd160
漩涡
sha3_224
sha3_256
sha3_384
sha3_512
您也可以将散列值存储在文件中或使用json格式化它们以便于解析。
这样做的好处是,您可以轻松地创建一个.bat文件以使其自动化。
如果您确实需要此程序,但比我更信任防病毒软件,请使用pyinstaller编译上述源代码。
安装python 3(注意32位/ 64位版本)
安装pyinstaller:
pip install pyinstaller
将源代码保存到名为hasher.py的文件中
运行命令:q4312 079q
4.5有时运行:
pyinstaller hasher.py
如果只需要单个文件可执行文件Profit
请注意,由于我没有时间,未测试编译后的exe的兼容性。
点击我进行下载。
#2 楼
rhash是可以计算单个哈希值的cmdline工具。您可以使用我的shellex.bat脚本在资源管理器上下文菜单中添加一个条目,该条目在控制台窗口中显示哈希。
例如,这将向每个文件添加“ CRC32”命令(粘贴并从批处理文件执行):
call shellex * CRC32 ""%~d0\PortableApps\ConEmu\ConEmu.exe" /cmd "%PROGRAMFILES%\Rhash\rhash.exe" -C --simple ""%%%%1"""
使用certuil的另一个选项是在这里。
Btw,对于小文件,我实际上更喜欢HashMyFiles,因为它具有更加用户友好的GUI。
评论
WinMD5仅计算MD5。HashMyFiles仅计算CRC32,MD5和SHA1
对于Windows?如果是,是否需要.NET?它至少应支持哪些散列?
@ wb9688:“可能需要.NET吗?”不会。NET依赖关系意味着在使用该应用程序之前,将迫使用户安装框架。这并不总是可能的。而且据我了解,还没有可移植的.NET。 “它至少应该支持什么哈希?”我想SHA-2是必需的。我认为SHA-3和Whirlpool会很不错。