ハッシュ値により 同一ファイルであるか判定するバッチ

##概要
ファイルサーバ上のファイル、メールの添付ファイル、ローカルに保存されたファイル...
散在しているファイルが、そのファイル名からして同一ファイルっぽい。
けれど念のために確認したい。
なんて事があるかと思います。

本バッチファイルは、複数のファイルについてハッシュ値から同一であるかの判定を行います。

##環境
Windows 10, Windows 7

##使用方法
* 比較したいファイル（複数可）を選択し、"cfHash.bat" ファイルにドラッグ（ファイルパスが引数に指定されてバッチが起動します）。

* 起動後にファイルパスの入力を求められるため、ファイルをDrag&Dropして [Enter]キーを押下します。ファイルパス（改行区切りで複数可能）をペーストする方法もあります。

* ハッシュ値が3パターン以上となるか、ファイル名を何も指定せずに [Enter]キーを押下すると、結果を画面出力して終了します。
※ログファイル "cfHash.log" にも結果が出力されます。

* ファイルのハッシュ値の算出には、Windows標準搭載のプログラム「CertUtil」を使用しています。

※内容の異なるファイルが、ハッシュ値の衝突により同一と誤判定される、すなわちフォールスポジティブが発生する可能性は限りなくゼロに近いですが（確率3*10^(-37)%未満）、判定結果の保証は致しかねますのでご了承ください。。

##ソースファイル
「マジック生成」するには、本ページ全体を選択してコピー後に[**B642FHT.bat**](https://qiita.com/X-IA/items/1db1929775e34ac7ef01)を起動して下さい。
その後、生成したZIPファイルを解凍して任意の場所へ配置して下さい。

興味ある方は、以下のコードをご覧ください。

###コード

```:cfHash.bat
@ECHO OFF
COLOR 0A
SETLOCAL ENABLEDELAYEDEXPANSION

ECHO ############## cfHash.bat ##############
ECHO # Comparing hash values of the files   #
ECHO #                                      #
ECHO #   Last update: 2019-05-11            #
ECHO #   Author: Y. Kosaka                  #
ECHO #   See the web for more information   #
ECHO #   https://qiita.com/x-ia             #
ECHO ########################################

SET fScr=%~dpn0
SET tScr=%~n0
SET extLog=.log
SET tAlg=SHA1
REM SET tAlg=MD5
REM SET tAlg=SHA256

SET cnt1=0
SET cnt2=0
SET list1=
SET list2=
SET list3=
SET hash1=
SET hash2=
SET hash3=

ECHO Using hash algorithm: %tAlg%

:loop
CALL :infile %1
IF %fInput% EQU "" GOTO eof
IF NOT EXIST %fInput% (
  ECHO File not exists.
  GOTO loop
)
CALL :gethash %fInput%
CALL :getsize %fInput%
CALL :compare
IF "%hash3%" NEQ "" (
  TITLE %tScr% %cnt1%, %cnt2%, 1 files
  GOTO eof
) ELSE IF "%hash2%" NEQ "" (
  TITLE %tScr% %cnt1%, %cnt2% files
) ELSE IF "%hash1%" NEQ "" (
  TITLE %tScr% %cnt1% files
)
SHIFT
GOTO loop


:eof
CALL :putout
ECHO Terminated.
PAUSE
EXIT /B


:infile
ECHO.
IF %1. NEQ . (
  SET fInput="%1"
  ECHO !fInput!
) ELSE (
  SET fInput=
  ECHO Enter the file to compare.
  ECHO (To exit, hit Enter key w/o any characters^)
  SET /P fInput=filepath= 
)
IF !fInput!. EQU . SET fInput=""
SET fInput="!fInput:"=!"
ECHO !fInput!
EXIT /B


:gethash
FOR /f "usebackq delims=" %%i IN (`certutil -hashfile %1 %tAlg% ^| FINDSTR /V :`) DO SET hash=%%i
ECHO %hash%
EXIT /B


:getsize
FOR %%i IN (%1) DO (SET nSize=%%~zi)
ECHO !nSize! bytes
EXIT /B


:compare
IF %cnt1% EQU 0 (
  SET list1=%fInput%
  SET hash1=%hash%
  SET /A cnt1=1
) ELSE IF "%hash%" EQU "%hash1%" (
  SET list1=!list1!	^

%fInput%
  SET /A cnt1=cnt1+1
) ELSE IF %cnt2% EQU 0 (
  SET list2=%fInput%
  SET hash2=%hash%
  SET /A cnt2=1
) ELSE IF "%hash%" EQU "%hash2%" (
  SET list2=!list2!	^

%fInput%
  SET /A cnt2=cnt2+1
) ELSE (
  SET list3=%fInput%
  SET hash3=%hash%
)
EXIT /B


:putout
ECHO.
ECHO %date% %time% %tScr% %tAlg%
ECHO pattern1 %cnt1% files
ECHO %date% %time% %tScr% %tAlg%>>%fScr%%extLog%
ECHO pattern1 %cnt1% files>>%fScr%%extLog%
IF "%hash1%" NEQ "" (
  ECHO !hash1!
  ECHO !list1!
  ECHO.
  ECHO !hash1!>>%fScr%%extLog%
  ECHO !list1!>>%fScr%%extLog%
  ECHO. >>%fScr%%extLog%
)

IF "%hash2%" NEQ "" (
  ECHO pattern2 %cnt2% files
  ECHO !hash2!
  ECHO !list2!
  ECHO.
  ECHO pattern2 %cnt2% files>>%fScr%%extLog%
  ECHO !hash2!>>%fScr%%extLog%
  ECHO !list2!>>%fScr%%extLog%
  ECHO.>>%fScr%%extLog%
)

IF "%hash3%" NEQ "" (
  ECHO pattern3
  ECHO !hash3!
  ECHO !list3!
  ECHO.
  ECHO pattern3>>%fScr%%extLog%
  ECHO !hash3!>>%fScr%%extLog%
  ECHO !list3!>>%fScr%%extLog%
  ECHO.>>%fScr%%extLog%
)

EXIT /B
```

###バイナリ (Base64 encoding)

```
cfHash.zip
---
UEsDBBQAAAAIAEJY8E77tgRnvQMAADELAAAKAAAAY2ZIYXNoLmJhdI1VW2+bShB+
riX/hzHVSrFOg81aOdKxRFWa4AaVmrSQo/QlKiHYoNisC+u2qar+9u4NDNjY5QF2
d2a/+ebKG/vy2gNvNuv3Lj3X+wRjq9/z7cD1Li0X7Ln11rWvbNf6zN53N9bcd7x5
v9fviWsvGw9Ei+uwSPSHkLYkpTpckvUmzNNsCQnThG/hahsXQBZAkxgW6YptAHbq
f/XU1d2woLDdPIY0ngIeG/+djy/ODaNL3drShORT+KzDe1KET+FxdD+OBdHv8QMs
SA5rkseQZmy5DmlKspZ6QummmI5GX9OUhnpE1qMf52nTxMuDgex+eORZcmDhR7mJ
fj9usrE8oPKg3MY/qEuWpr4iSyW3VkvTv7aMfu+T/QGqow9XF60TpoQv/i0NRRk1
zHG1xuV6lRZMsFvj2nqi1jzFRm2Na2uuo3y/Lap6CFdLkqc0WU8BcTKIK01XhGxY
dVquC1MWbVYlgJgfzgzQwsk2W4rA/ngLmgbvvMCDmCyEcO4FYN85frBTO+v3AITR
GUfJCGWRYowLnQvEbWlsWNpbxlQwKyFq50X6M947j0SBx4KAhoSnSIO5/ZHTE+YD
J3Bt5h5LGALE44teiS9mX0M2QcVG+DIE2/VtqBDx3yOWcG0I4zREdZUl7dqZBf1e
LT4iL4KcdJuFgGypSmgQ5+s0Yy34yMJ6Y936NhPcOQGM3qqbMotSXZeZNHRBSJd8
RI2LyJoaMrQqbQN5OKg8amtXmnZG47waK0AJqNTolcpZQHj66StIUqouPMXP8H1E
IMyeIUrCPIzYaXE/LM2MbkpLHHYT0sQEESPmQ0lOF+WoN5zQVN+qrVKdauZAU1Hb
udaMlarAfm/GhvNoAdq2iB/C6OkrPMardF2YGiCUgjOHsy9RnNMtTVdwzq+oTlGt
BPe/YObMr/yAwfwP0y9DuPKg7EeTYSgiokDQARq84CWN0iAyBMgZR8l8JmYwv3+m
w9IlcTaAh2fKK6kJWO8UVXE8bONdSuWM2XUYVGzZqSKpsmLJQWXsVzordDEcqrJv
wQ/EZ/DinpNq2ypx+eufBrhqrwOM8UHG+CBjfJIxbjPGkjE+yhhzxrjGuAExOchw
UjEctlNV7269rBL+j2WzgqZr8ZGTQw1tocGag/VOZrTmyanbr18j/ndDSP7DjqLt
63ZOOFmQQjLY7WXyy73eVtzHb17skuuwLxnyUHbO8LqPuDW865xwizw+QP4gTLcr
Eva4q91y/ZSn7f9fneKkyWLScm7S7dzkuD+TE/50y7v8qTriD1BLAQIUABQAAAAI
AEJY8E77tgRnvQMAADELAAAKAAAAAAAAAAEAIAAAAAAAAABjZkhhc2guYmF0UEsF
BgAAAAABAAEAOAAAAOUDAAAAAA==
---
```