SHA256 hash and filename on one line

Started by raywood, December 04, 2021, 02:55:04 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

raywood

I plan to use something like

certUtil -hashfile "D:\path\to\file.doc" SHA256 | findstr /v "hash"
to produce the hash for a specified file. I will be running a number of similar commands, to calculate hashes for other files, in a batch file.

I would like to output the results in a spreadsheet-friendly form, with output consisting of path - delimiter - hash on a single line. The command as just shown doesn't output the filename.

Alternately, I could leave off the pipe, but that gives me the filename on one line and the hash on the next line, along with other verbiage.

In some instances, I will be seeking hashes for all files in a folder. For that, I wouldn't want to write commands for each individual file. I would presumably use something like this:

(for %i in (*.*) do COMMAND '%i') > hashlist.txt

where COMMAND would presumably be an adaptation of the single-file command (above). I'm a little shaky on the syntax involved in adapting one-line commands to loops.

So I'm asking for help with two things:

(1) How to output the delimited file path and hash on one line of a text file.
(2) Advice on modifying that command for use in a loop, to apply to all files in a folder and subfolders.

Hackoo

Hi  ;)
Give a try for this batch file : Just change the Folder to be scanned. In this example i have chosen : C:\temp

SHA256_Multi-Files_In_Folder.bat

@echo off & Color 0B
Title Get SHA256 of Multi-Files in Folder with Certutil Command
Set "Folder=C:\temp"
Set "OutPutFile=%~dp0HashList.csv"
Type nul>"%OutPutFile%"

SetLocal EnableDelayedExpansion
@for /f "delims=" %%a in ('Dir /S /B /A-D "%Folder%"') do (
@for /f "skip=1 delims=" %%H in ('CertUtil -hashfile "%%~a" SHA256 ^| findstr /i /v "CertUtil"') do set "Hash=%%H"
echo %%a,!Hash: =!
echo %%a,!Hash: =! >>"%OutPutFile%"
)
Start "" "%OutPutFile%" & Exit





raywood

Hackoo, thank you -- that works. There is a bug -- it sees a comma in a filename as a delimiter.

Squashman: I tried this:

hashsum /s /t /a sha256 *.* > hashlist.txt

That worked. Ideally, it would (a) replace the asterisk with nothing, leaving just a single space delimiting the hash from the filename, and (b) add a slash before the name of a subdirectory. Those may be things that I can eventually figure out how to adjust. Neither seems to diminish the desired functionality.

I also tried this:

hashsum /s /t /a sha256 hashsum.bat

That worked too: as with the bulk output, it gave me the code, two spaces, and then the filename, all on a single line.

At present, that looks like exactly what I need. I appreciate both of these quick and useful responses.

This outcome raises two further questions:

(1) I'm not familiar with the differences between this forum (ComputerHope) and DOSTips.com. I got a good answer quickly; I'm satisfied. But for next time, are there differences between the two that should influence my choice of where to post? I'm not a particularly sophisticated batch coder. I did think about posting my question there. Now I wonder whether it's maybe for more advanced DOS users.

(2) It appears that modern GPUs calculate hashes very much faster than CPUs. It also seems that some hash software is designed for GPUs, and some for CPUs. My application for this hash question is security-related. I don't presently have a graphics card. But if I do buy one, I would not like to find that the bad guys are using my GPU to crack codes that seemed to take my CPU a long time. Is HASHSUM.BAT using the CPU? I would assume so. For present purposes, is there anything I should know, or anything I can do, about using HASHSUM.BAT with or without a GPU?

raywood

#4
A third question: is there a Linux tool that can likewise produce hash and filename, for a single file or a folder full of files, on a single line of output? I see this for single files:

sha256sum filename.ext

As soon as I wrote that question, I realized that I should post it in a Linux forum. But there's no Delete button here. Second-best, I think I found an answer:

rhash --sha3-256 -r /path/to/filename.ext

Squashman

If you happened to read the code, hashsum.bat is just a wrapper for certutil but also provides extra useful functions for validating hashsums as well.

raywood

I looked at enough of the code to realize that it was well beyond my present ability. Now that you clue me in, I do see a reference to certUtil in a loop that appears to be at the heart of it. Which I guess is for the best: certUtil seems to come highly recommended.

A little further exploration calls for a correction to my statement about rhash: it looks like certUtil doesn't do SHA3, so the rhash command should use --sha256, not sha3-256. Also, apparently its specification of a file is optional; just stating the folder will work too.

raywood

#7
An update. I ran commands like those shown above, using rhash and hashsum on the same test folder. I found that hashsum seemed to ignore about 1% of files. There did not seem to be a single reason. In some cases, I saw that the excluded files contained atypical characters in their names, notably an em dash (—). But that was not the only explanation. Other ignored files included a simple text file named x.txt, having no weird characters in either filename or contents, and .wav files with normal titles and no textual contents.

While hashsum was running, it produced a number of warnings reading simply, "0 was unexpected at this time." I did not count the number of those messages. They did not state which file they were referring to. Possibly those could provide some insight into why hashsum was unwilling or unable to produce hashes for a number of files that posed no apparent problem for rhash.

These results left me with the impression that hashsum was buggy. There may have been a better explanation -- a reason, perhaps, why rhash should have produced no value for these ~20 files. But at present it seemed that I should resume the search for a Windows hash tool with the features described above.

(Echoed at https://www.dostips.com/forum/viewtopic.php?f=3&t=7592&p=65648#p65648)


Squashman

You didn't give us any technical feedback on Dostips.com to solve the problem you were having with hashsum.bat. I guess now we will never know what the problem might be.

Regardless, that was a long read for something that should be rather simple to accomplish.  When I took my first linux class back in 90's, we were required to do checksums of our servers every class.

Squashman

Read Dave's Post about unicode characters being in your file names.
https://www.dostips.com/forum/viewtopic.php?f=3&t=7592&start=45#p63708

This is from the help file.
    /U - Unicode mode: Experimental setting that attempts to support
         Unicode in filenames. Please report any problems to the DosTips
         forum at https://www.dostips.com/forum/viewtopic.php?f=3&t=7592

raywood

With the aid of further research, I've revised the technique:

for %%A in (*) do (
  (
    <nul set /p "=%%~tA %%~zA "
    certutil -hashfile "%%A" SHA256 | find /V ":"
    <nul set /p "=%%~dpnxA"
  )
)


The problem here is that the output doesn't stay on one line. Certutil seems to force a new line. The <nul set /p technique doesn't seem to work with the certutil line. Sample output:

04/03/2022 05:00 PM 265 97f806448bfad1ddf885ce656e612c29ec55b52fea
D:\Folder name\File name.txt


I would rather not put the certutil line last. The path information generated by the last line (i.e., <nul set /p "=%%~dpnxA") is likely to introduce spaces that may complicate importing into a spreadsheet. All other fields are space-delimited. To make the best use of the spreadsheet's ability to detect fields by the spaces around them, ideally I would put the path at the end of the output line.