2021-06-14

PowerShell計算SHA1 Hash

產生sha1物件
計算hash:ComputeHash
計算hash:TransformBlock、TransformFinalBlock
兩種方式的差別

產生sha1物件

任選其中一行執行即可
PS R:\> $sha1 = [System.Security.Cryptography.SHA1]::Create()
PS R:\>
PS R:\> $sha1 = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider
PS R:\> $sha1 = [System.Security.Cryptography.SHA1CryptoServiceProvider]::new()
PS R:\>
PS R:\> $sha1 = New-Object System.Security.Cryptography.SHA1Managed
PS R:\> $sha1 = [System.Security.Cryptography.SHA1Managed]::new()
PS R:\>
PS R:\> $sha1 = New-Object System.Security.Cryptography.SHA1Cng
PS R:\> $sha1 = [System.Security.Cryptography.SHA1Cng]::new()
PS R:\>

計算hash:ComputeHash

資料來源:byte[]
PS R:\> $sha1 = [System.Security.Cryptography.SHA1]::Create()
PS R:\> [byte[]]$data = 11, 12, 13
PS R:\> $r = $sha1.ComputeHash($data)
PS R:\> $r.gettype().name
Byte[]
PS R:\> $r.count
20
PS R:\> [System.BitConverter]::ToString($r)
0D-52-37-C1-4C-75-22-CD-24-6A-D7-67-38-26-25-6F-A5-62-0A-80
PS R:\>
PS R:\> [System.BitConverter]::ToString($r) -replace '-',''
0D5237C14C7522CD246AD7673826256FA5620A80
PS R:\>
另一種方式
byte[] ComputeHash(byte[] buffer, int offset, int count)
資料來源:System.IO.Stream
PS R:\> $sha1 = [System.Security.Cryptography.SHA1]::Create()
PS R:\> $file = dir 1.jpg
PS R:\> $fs = $file.OpenRead()
PS R:\> $r = $sha1.ComputeHash($fs)
PS R:\>
PS R:\> [System.BitConverter]::ToString($r)
1E-AC-FE-49-4E-67-6D-CE-99-7C-41-85-8C-1F-3A-81-AC-F7-C2-A5
PS R:\>
PS R:\> [System.BitConverter]::ToString($r) -replace '-',''
1EACFE494E676DCE997C41858C1F3A81ACF7C2A5
PS R:\> $fs.close()
PS R:\>

計算hash:TransformBlock、TransformFinalBlock

TransformFinalBlock 一次讀取
PS R:\> $sha1 = [System.Security.Cryptography.SHA1]::Create()
PS R:\> [byte[]]$data = 11, 12, 13
PS R:\>
PS R:\> $sha1.TransformFinalBlock($data, 0, $data.Length)
11
12
13
PS R:\> $sha1.Hash.gettype().name
Byte[]
PS R:\> [System.BitConverter]::ToString($sha1.Hash)
0D-52-37-C1-4C-75-22-CD-24-6A-D7-67-38-26-25-6F-A5-62-0A-80
PS R:\>
PS R:\> $sha1.Initialize()
PS R:\>
byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
傳回值:剛剛讀取的資料

執行完TransformFinalBlock之後,可以從$sha1.Hash取得Hash

如果要計算下一個資料的Hash,要用$sha1.Initialize()重設狀態
如果不再使用$sha1物件,用$sha1.Clear();   $sha1.Dispose()
TransformBlock的介紹
PS R:\> $sha1 = [System.Security.Cryptography.SHA1]::Create()
PS R:\> [byte[]]$data = 11, 12, 13
PS R:\> $out = New-Object byte[] 5
PS R:\> $sha1.TransformBlock($data, 0, $data.Length, $out, 0)
3
PS R:\> "$out"
11 12 13 0 0
PS R:\>
int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
傳回值:讀取了多少資料

會把讀取的資料寫到outputBuffer
也可寫成:
$sha1.TransformBlock($data, 0, $data.Length, $data, 0)
$sha1.TransformBlock($data, 0, $data.Length, $null, 0)
TransformBlock  TransformFinalBlock 分次讀取
PS R:\> $sha1 = [System.Security.Cryptography.SHA1]::Create()
PS R:\> [byte[]]$data = 11, 12, 13
PS R:\> $sha1.TransformBlock($data, 0, $data.Length, $null, 0) > $null
PS R:\> [byte[]]$data2 = 21, 22, 23
PS R:\> $sha1.TransformBlock($data2, 0, $data2.Length, $null, 0) > $null
PS R:\>
PS R:\>
PS R:\> $sha1.TransformFinalBlock($data, 0, 0) > $null
PS R:\> [System.BitConverter]::ToString($sha1.Hash)
60-92-DE-71-DB-96-D8-F9-C6-BC-57-14-BB-D9-FA-54-D3-42-7F-A4
PS R:\>
當TransformBlock已經讀取過資料,TransformFinalBlock可以讀取資料,也可以不讀取資料

不讀取資料時:
    可以寫成$sha1.TransformFinalBlock($data, 0, 0)
    不可以寫成$sha1.TransformFinalBlock($null, 0, 0)

兩種方式的差別

ComputeHash
    每次計算完會自動重設狀態,不用 $sha1.Initialize()
    傳回值,即是hash
    
    可以讀取 System.IO.Stream

TransformFinalBlock
    得到hash之後,如果還要計算別的資料的hash,
    要用$sha1.Initialize() 重設狀態

    傳回值不是hash
ComputeHash自動重設狀態
PS R:\> $sha1 = [System.Security.Cryptography.SHA1]::Create()
PS R:\> [byte[]]$data = 11, 12, 13
PS R:\>
PS R:\> $r = $sha1.ComputeHash($data)
PS R:\> [System.BitConverter]::ToString($r)
0D-52-37-C1-4C-75-22-CD-24-6A-D7-67-38-26-25-6F-A5-62-0A-80
PS R:\>
PS R:\>
PS R:\> $r = $sha1.ComputeHash($data)
PS R:\> [System.BitConverter]::ToString($r)
0D-52-37-C1-4C-75-22-CD-24-6A-D7-67-38-26-25-6F-A5-62-0A-80

沒有留言:

張貼留言