
Si bien esto es fácil de hacer en el mundo *nix, no puedo encontrar una solución para generar un hash SHA256 de uncadenadesde el shell de comandos de Windows (no PowerShell) sin instalar una aplicación de terceros o un archivo por lotes.
CertUtil funciona bien para generar un hash de un archivo, pero quiero el hash de una cadena simple para que algunos desarrolladores puedan copiarlo y pegarlo para que lo utilicen en otros lugares.
Estoy buscando algo en Windows que funcione como esto en una Mac:
echo -n "foobar" | shasum -a 256
Eso genera un hash de "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2".
Cualquier ayuda sería apreciada. Soy un usuario de Mac y solo estoy intentando reunir algunos documentos para nuestros desarrolladores, y algunos de ellos usan Windows.
Respuesta1
Script por lotes/cmd de Windows
Elcertificadono admite la entrada desde una tubería, sino solo
certutil [options] -hashfile infile [hashalgorithm]
Por lo tanto, se requiere un archivo temporal.
Este script cmd de Windows toma una cadena como argumento y devuelve el hash SHA-256.
@echo off
if [%1]==[] goto usage
set STRING="%*"
set TMPFILE="%TMP%\hash-%RANDOM%.tmp"
echo | set /p=%STRING% > %TMPFILE%
certutil -hashfile %TMPFILE% SHA256 | findstr /v "hash"
del %TMPFILE%
goto :eof
:usage
echo Usage: %0 string to be hashed
Un ejemplo, donde se nombra este script sha256sum.cmd
:
C:\>sha256sum.cmd
Usage: sha256sum.cmd string to be hashed
C:\>sha256sum.cmd foobar
c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
C:\>sha256sum.cmd foo bar
fbc1a9f858ea9e177916964bd88c3d37b91a1e84412765e29950777f265c4b75
Estos son los mismos hashes que con sha256sum
:
$ echo -n "foobar" | sha256sum
c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 -
$ echo -n "foo bar" | sha256sum
fbc1a9f858ea9e177916964bd88c3d37b91a1e84412765e29950777f265c4b75 -
Potencia Shell
ElGet-FileHash
cmdletapoyaflujos de entradaque puede reemplazar los archivos temporales.
Basado en elejemplo 4es posible recrear el script cmd anterior en PowerShell:
if($args.Count -eq 0) {
Write-Host "Usage: .\$($MyInvocation.MyCommand.Name) string to be hashed";
exit 1
}
$stringAsStream = [System.IO.MemoryStream]::new()
$writer = [System.IO.StreamWriter]::new($stringAsStream)
$writer.write("$args")
$writer.Flush()
$stringAsStream.Position = 0
Get-FileHash -Algorithm SHA256 -InputStream $stringAsStream `
| Select-Object Hash `
| ForEach-Object {$_.Hash}
Un ejemplo, donde se nombra este script sha256sum.ps1
:
PS C:\> .\sha256sum.ps1
Usage: .\sha256sum.ps1 string to be hashed
PS C:\> .\sha256sum.ps1 foobar
C3AB8FF13720E8AD9047DD39466B3C8974E592C2FA383D4A3960714CAEF0C4F2
PS C:\> .\sha256sum.ps1 foo bar
FBC1A9F858EA9E177916964BD88C3D37B91A1E84412765E29950777F265C4B75
Respuesta2
OP solicitó una frase breve que no requiere "ejecutar" un archivo por lotes, por lo que aquí está dicha frase, derivada del comentario de @GeraldSchneider yesta respuesta:
echo|set /p="foobar" > %TMP%/hash.txt |certutil -hashfile %TMP%/hash.txt SHA256 | findstr /v "hash"