如何在PowerShell中获取MD5校验和
我想计算一些内容的校验和。如何在PowerShell中执行此操作?此站点有一个示例:。它使用.NET framework实例化MD5哈希算法的一个实例来计算哈希 以下是文章中的代码,包括Stephen的评论:如何在PowerShell中获取MD5校验和,powershell,powershell-2.0,Powershell,Powershell 2.0,我想计算一些内容的校验和。如何在PowerShell中执行此操作?此站点有一个示例:。它使用.NET framework实例化MD5哈希算法的一个实例来计算哈希 以下是文章中的代码,包括Stephen的评论: param ( $file ) $algo = [System.Security.Cryptography.HashAlgorithm]::Create("MD5") $stream = New-Object System.IO.FileStream($Path, [System.I
param
(
$file
)
$algo = [System.Security.Cryptography.HashAlgorithm]::Create("MD5")
$stream = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open,
[System.IO.FileAccess]::Read)
$md5StringBuilder = New-Object System.Text.StringBuilder
$algo.ComputeHash($stream) | % { [void] $md5StringBuilder.Append($_.ToString("x2")) }
$md5StringBuilder.ToString()
$stream.Dispose()
如果内容是字符串:
$someString = "Hello, World!"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = New-Object -TypeName System.Text.UTF8Encoding
$hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($someString)))
如果内容是文件:
$someFilePath = "C:\foo.txt"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
从PowerShell版本4开始,使用cmdlet可以很容易地对开箱即用的文件执行此操作:
Get FileHash-算法MD5
这当然更可取,因为它避免了第一个解决方案在注释中指出的问题(使用流、关闭流并支持大文件)。以下是两行,只需更改第2行中的“hello”: 如果您使用的是Get Hash命令,则可以轻松地执行此操作:
C:\PS> "hello world" | Get-Hash -Algorithm MD5
Algorithm: MD5
Path :
HashString : E42B054623B3799CB71F0883900F2764
网上有很多使用ComputeHash()的示例。我的测试表明,当通过网络连接运行时,速度非常慢。下面的代码片段对我来说运行速度快得多,但是您的里程数可能会有所不同:
$md5 = [System.Security.Cryptography.MD5]::Create("MD5")
$fd = [System.IO.File]::OpenRead($file)
$buf = New-Object byte[] (1024*1024*8) # 8 MB buffer
while (($read_len = $fd.Read($buf,0,$buf.length)) -eq $buf.length){
$total += $buf.length
$md5.TransformBlock($buf,$offset,$buf.length,$buf,$offset)
Write-Progress -Activity "Hashing File" `
-Status $file -percentComplete ($total/$fd.length * 100)
}
# Finalize the last read
$md5.TransformFinalBlock($buf, 0, $read_len)
$hash = $md5.Hash
# Convert hash bytes to a hexadecimal formatted string
$hash | foreach { $hash_txt += $_.ToString("x2") }
Write-Host $hash_txt
下面是我用来处理相对路径和绝对路径的函数:
function md5hash($path)
{
$fullPath = Resolve-Path $path
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$file = [System.IO.File]::Open($fullPath,[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)
try {
[System.BitConverter]::ToString($md5.ComputeHash($file))
} finally {
$file.Dispose()
}
}
感谢@davor上面的建议使用Open()而不是ReadAllBytes(),感谢@jpmc26建议使用finally块。这将为远程计算机上的文件返回MD5哈希:
Invoke-Command -ComputerName RemoteComputerName -ScriptBlock {
$fullPath = Resolve-Path 'c:\Program Files\Internet Explorer\iexplore.exe'
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$file = [System.IO.File]::OpenRead($fullPath)
$hash = [System.BitConverter]::ToString($md5.ComputeHash($file))
$hash -replace "-", ""
$file.Dispose()
}
如果从Microsoft下载文件校验和完整性验证器(FCIV),这将成为一行代码 我从这里下载了FCIV: 运行以下命令。我有十份文件要查
Get-ChildItem WTAM*.tar | % {.\fciv $_.Name}
右键单击菜单选项的示例:
[HKEY_CLASSES_ROOT\*\shell\SHA1 PS check\command]
@="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -NoExit -Command Get-FileHash -Algorithm SHA1 '%1'"
现在有一个Get FileHash函数,非常方便
PS C:\> Get-FileHash C:\Users\Andris\Downloads\Contoso8_1_ENT.iso -Algorithm SHA384 | Format-List
Algorithm : SHA384
Hash : 20AB1C2EE19FC96A7C66E33917D191A24E3CE9DAC99DB7C786ACCE31E559144FEAFC695C58E508E2EBBC9D3C96F21FA3
Path : C:\Users\Andris\Downloads\Contoso8_1_ENT.iso
只需将SHA384更改为MD5即可
。文档中有更多示例。这里是一个尝试验证SHA256指纹的漂亮打印示例。我使用PowerShell v4下载了gpg4win v3.0.3(需要
Get FileHash
)
从下载包,打开PowerShell,从下载页面获取哈希,然后运行:
cd ${env:USERPROFILE}\Downloads
$file = "gpg4win-3.0.3.exe"
# Set $hash to the hash reference from the download page:
$hash = "477f56212ee60cc74e0c5e5cc526cec52a069abff485c89c2d57d1b4b6a54971"
# If you have an MD5 hash: # $hashAlgo="MD5"
$hashAlgo = "SHA256"
$computed_hash = (Get-FileHash -Algorithm $hashAlgo $file).Hash.ToUpper()
if ($computed_hash.CompareTo($hash.ToUpper()) -eq 0 ) {
Write-Output "Hash matches for file $file"
}
else {
Write-Output ("Hash DOES NOT match for file {0}: `nOriginal hash: {1} `nComputed hash: {2}" -f ($file, $hash.ToUpper(), $computed_hash))
}
输出:
True
文件gpg4win-3.0.3.exe的哈希匹配
另一个在Windows中默认安装的内置命令可以追溯到2003年,它当然也可以从PowerShell调用
CertUtil -hashfile file.foo MD5
(注意:MD5应该全部大写,以获得最大的健壮性)这里是一个单行命令示例,它计算文件的正确校验和,就像您刚才下载的一样,并将其与原始文件的已发布校验和进行比较 例如,我写了一个例子。在这种情况下,您有:
PS C:\Distr> (Get-FileHash .\apache-jmeter-4.0.zip -Algorithm MD5).Hash -eq (Get-Content .\apache-jmeter-4.0.zip.md5 | Convert-String -Example "hash path=hash")
输出:
True
说明:
-eq
运算符的第一个操作数是计算文件校验和的结果:
(Get-FileHash .\apache-jmeter-4.0.zip -Algorithm MD5).Hash
第二个操作数是已发布的校验和值。我们首先获取file.md5的内容,它是一个字符串,然后根据字符串格式提取哈希值:
Get-Content .\apache-jmeter-4.0.zip.md5 | Convert-String -Example "hash path=hash"
file和file.md5必须位于同一文件夹中才能执行此命令。如接受答案中所述,易于与文件一起使用,但也可以与字符串一起使用:
$s = "asdf"
Get-FileHash -InputStream ([System.IO.MemoryStream]::New([System.Text.Encoding]::ASCII.GetBytes($s)))
这就是我用来获得一致哈希值的方法:
函数新CrcTable{
[uint32]$c=$null
$crcTable=新对象“System.Uint32[]”256
对于($n=0;$n-lt 256;$n++){
$c=[uint32]$n
对于($k=0;$k-lt 8;$k++){
如果($c-波段1){
$c=(0xEDB88320-bxor($c-shr 1))
}
否则{
$c=($c-shr 1)
}
}
$crcTable[$n]=$c
}
写入输出$crcTable
}
函数更新Crc([uint32]$Crc,[byte[]]$buffer,[int]$length,$crcTable){
[uint32]$c=$crc
对于($n=0;$n-lt$length;$n++){
$c=($c-bxor$buffer[$n])-band 0xFF])-bxor($c-shr 8)
}
写入输出$c
}
函数Get-CRC32{
[CmdletBinding()]
param(
#用于CRC计算的字节数组
[参数(位置=0,ValueFromPipeline=$true)]
[ValidateNotNullOrEmpty()]
[字节[]]$InputObject
)
$dataArray=@()
$crcTable=新的crcTable
foreach($InputObject中的项){
$dataArray+=$item
}
$inputLength=$dataArray.Length
写入输出((更新Crc-Crc 0xffffffffL-buffer$DATARRAY-length$INPUTLENGHT-crcTable$crcTable)-bxor 0xffffffffL)
}
函数GetHash(){
[CmdletBinding()]
param(
[参数(位置=0,ValueFromPipeline=$true)]
[ValidateNotNullOrEmpty()]
[string]$InputString
)
$bytes=[System.Text.Encoding]::UTF8.GetBytes($InputString)
$hasCode=Get-CRC32$bytes
$hex=“{0:x}”-f$hasCode
返回$hex
}
函数Get FolderHash{
[CmdletBinding()]
param(
[参数(位置=0,ValueFromPipeline=$true)]
[ValidateNotNullOrEmpty()]
[字符串]$FolderPath
)
$FolderContent=新对象System.Collections.ArrayList
获取ChildItem$FolderPath-递归| Where对象{
如果([System.IO.File]::存在($\ux)){
$FolderContent.AddRange([System.IO.File]::ReadAllBytes($)| Out Null
}
}
$hasCode=Get-CRC32$FolderContent
$hex=“{0:x}”-f$hasCode
返回$hex.Substring(0,8).ToLower()
}
以下是我用来获取给定字符串的MD5的代码片段:
$text = "text goes here..."
$md5 = [Security.Cryptography.MD5CryptoServiceProvider]::new()
$utf8 = [Text.UTF8Encoding]::UTF8
$bytes= $md5.ComputeHash($utf8.GetBytes($text))
$hash = [string]::Concat($bytes.foreach{$_.ToString("x2")})
PowerShell一行程序(字符串到散列)
MD5
沙一
SHA256
([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")
沙384
([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")
SHA512
([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")
什么是“一些内容”?档案?字符串?使用“1”参数调用“ReadAllBytes”时出现异常:“文件太长。此操作当前仅限于支持小于2 GB的文件(秒)。”
([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")
([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")
([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")