奇怪的是,但是我找不到可移植的应用程序来为所选文件计算一个不同的哈希(类型,例如SHA256,SHA512,Whirlpool,SHA3?)!这就是我所发现的全部内容:



RapidCRCUnicodePortable-它具有非常用户不友好的行为。我看到了什么?我打开此应用程序,单击“打开文件”按钮,然后选择我的文件。我在列表中看到文件名,并在右侧看到一条奇怪的消息:“未找到哈希”。好的,我单击“ SHA256文件”按钮,然后看到以下消息:“您必须先计算sha256校验和。单击确定立即执行。”我单击确定。现在,文件名在列表中重复了,并在右侧带有相同的“未找到哈希”文本,但是现在–恭喜! –我终于可以将找到的SHA256哈希复制到剪贴板。奇怪的是,当我从列表中删除文件时,此应用程序在系统中崩溃。我不明白这个错误是怎么存在的。它使我认为该软件不稳定。

ChecksumControlPortable仅用于创建SFV / MD5文件。顺便说一句,它甚至无法通过资源管理器选择单独的文件,它使用拖放界面,但是我讨厌这种界面。我从不使用拖放。
HashGenerator浪费大量时间,CPU周期一次计算所有类型的哈希。处理大型文件时,它会使该应用程序变得极为用户不友好。

有Multihasher,但是它不支持某些重要的哈希类型,例如SHA-3和Whirlpool。HashTab满足了我的所有需求,但是...真可惜!它是可安装的dll,无需便携式应用程序即可进行系统集成。
实际上,我对这种情况感到有些震惊。我从没想到过我无法找到合适的软件来解决这种常见问题。

评论

WinMD5仅计算MD5。

HashMyFiles仅计算CRC32,MD5和SHA1

对于Windows?如果是,是否需要.NET?它至少应支持哪些散列?

@ wb9688:“可能需要.NET吗?”不会。NET依赖关系意味着在使用该应用程序之前,将迫使用户安装框架。这并不总是可能的。而且据我了解,还没有可移植的.NET。 “它至少应该支持什么哈希?”我想SHA-2是必需的。我认为SHA-3和Whirlpool会很不错。

#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。