4

I would like to rename all files in a folder to their SHA1 HASH value.

I have a command line utility that I can use "sha1.exe -s" to echo out the SHA1 Hash value but I need to rename all the files in that folder to match it (no extension).

Essentially, I would like it to function like this:

rename file.exe (sha1.exe -s file.exe)

In practice turns out something like this:

forfiles /p E:\software\sha1 /c "cmd /c rename @file (sha1.exe -s @file)"

I am open to using other resources such as Powershell if that's what is required.

I appreciate any help!

3 Answers 3

2

Create a file hasher.bat (for ease place sha1.exe in same folder):

@ECHO OFF
SET FULLNAME=%~f1
for /f "delims=" %%a in ('sha1.exe -s %FULLNAME%') do SET hash=%%a
ren %FULLNAME% %hash%

Now in CMD you can run the batch using following statement:

for %A IN (C:\PathToFolder\*) DO C:\SomeFolder\hasher.bat "%A"

1
  • This is perfect! For simplicity sake I put sha1.exe in the "c:\windows" folder and created another batch file that can invoke the hasher.bat file: for %%A IN (C:\PathToFolder*) DO C:\SomeFolder\hasher.bat "%%A"
    – Craysh
    Feb 13, 2013 at 3:16
1

I'm not familiar with a forfiles command, nor a /P option to any for-like commands I know, so I'm guessing that E:\software\sha1 is a text file listing the files you want to operate on, one path per line.

Get-Content E:\software\sha1 |
    foreach {
        ren $_ (sha1.exe -s $_)
    }

or if you're typing it by hand:

gc E:\software\sha1 | % { ren $_ (sha1.exe -s $_) }
1
  • Actually the /P option accepts a directory to get the listing to operate from. So if you replace Get-Content with Get-ChildItem, you're golden.
    – zdan
    Feb 12, 2013 at 22:13
0

The .Net framework has hashing features built in. Here's how to do it in powershell without using additional utilities.

function Rename-FilesToSHA {
    [CmdletBinding()]
    Param(
    [ValidateScript({ Test-Path $_ })]
    $Path
    )

    $hasher = [System.Security.Cryptography.HashAlgorithm]::Create('SHA1')
    $files = Get-ChildItem $Path -Recurse | Where-Object {-not $_.PSIsContainer}

    foreach ($file in $files) {

    $fs = New-Object IO.FileStream($file.FullName, 'Open')
    $sb = New-Object System.Text.StringBuilder

    $hasher.ComputeHash($fs) | ForEach-Object { [void]$sb.Append($_.ToString("x2")) }
    $fs.Close()

    $file | Rename-Item -NewName $sb.ToString()
    }
}

For example to rename all files under c:\temp run the command:

Rename-FilesToSHA -Path c:\temp

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .