C#中計算流指定位置和長度的MD5值
在Microsoft .NET Framework 2.0中,計算MD5值可以用到System.Security.Cryptography.MD5CryptoServiceProvider類,其計算MD5的方法ComputeHash()有三個過載方法。
名稱 | 說明 | |
---|---|---|
ComputeHash(Byte[]) | 計算指定位元組陣列的雜湊值。 (繼承自 HashAlgorithm。) | |
ComputeHash(Stream) | 計算指定 Stream 物件的雜湊值。 (繼承自 HashAlgorithm。) | |
ComputeHash(Byte[], Int32, Int32) | 計算指定位元組陣列的指定區域的雜湊值。 (繼承自 HashAlgorithm。) |
如果需要計算檔案流中指定區域的雜湊值(如大檔案傳輸斷點續傳)時,這三個方法就不夠用了,我們需要一個如下的過載方法:
名稱 | 說明 | |
---|---|---|
ComputeHash(Stream,Int32,Int32) | 計算指定 Stream 物件的指定區域的雜湊值。(繼承自 HashAlgorithm。) |
不過微軟並沒有提供這個方法來計算流中指定區域的MD5值。通過反編譯mscorlib.dll與檢視微軟公佈的Framework部分原始碼,發現Windows 2000 Professol與Windows XP及以上作業系統提供了一個 "Cryptdll.dll”,其中有3個關於計算MD5的API函式:
MD5Init
The MD5Init function initializes an MD5 message digest context. The context must be initialized for any new MD5 message digest. This function is defined by RSA.
void MD5Init(
MD5_CTX* context
);
MD5Update
The MD5Update function updates the MD5 context by using the supplied buffer for the message whose MD5 digest is being generated. This function is called for each buffer of the message being hashed. This function is defined by RSA.
void MD5Update(
MD5_CTX context,
unsigned char* input,
unsigned int inlen
);MD5Final
The MD5Final function ends an MD5 message digest previously started by a call to the MD5Init function. Prior to calling MD5Final, use the MD5Update function to update the MD5 message digest context with each buffer in the message being hashed. This function is defined by RSA.
void MD5Final(
MD5_CTX context
);有了這些準備,就可以實現計算流中指定區域的MD5值了,下面是MyMD5類的原始碼:
2 { [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
3 public struct MD5_CTX
4 {
5 /// ULONG[2] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = System.Runtime.InteropServices.UnmanagedType.U4)]
6 public uint[] i;
7 /// ULONG[4] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.U4)]
8 public uint[] buf;
9 /// unsigned char[64] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 64)]
10 public byte[] @in;
11 /// unsigned char[16]
12 [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 16)]
13 public byte[] digest;
14 }
15
16 [DllImport("cryptdll.dll")]
17 public static extern void MD5Init(ref MD5_CTX context);
18 [DllImport("cryptdll.dll")]
19 public static extern void MD5Update(ref MD5_CTX context, Byte[] input, Int32 inlen);
20 [DllImport("cryptdll.dll")]
21 public static extern void MD5Final(ref MD5_CTX context);
22
23 MD5_CTX md5data = new MD5_CTX();
24 protected override void HashCore(byte[] array, int ibStart, int cbSize)
25 {
26 if (ibStart != 0)
27 {
28 byte[] tmparray = new byte[cbSize - ibStart];
29 array.CopyTo(tmparray, ibStart);
30 array = tmparray;
31 }
32 MD5Update(ref md5data, array, cbSize);
33 }
34
35 protected override byte[] HashFinal()
36 {
37 MD5Final(ref md5data);
38 return md5data.digest;
39 }
40
41 public MyMD5()
42 {
43 Initialize();
44 }
45 public override void Initialize()
46 {
47 MD5Init(ref md5data);
48 }
49
50 public byte[] ComputeHash(Stream inputStream, int offset, long count)
51 {
52 int num;
53 long totalHashCount = 0;
54
55 byte[] buffer = new byte[0x1000];
56 do
57 {
58 int readCount = buffer.Length;
59 if (count - totalHashCount < buffer.Length)
60 {
61 readCount = (int)(count - totalHashCount);
62 }
63 num = inputStream.Read(buffer, 0, readCount);
64 if (num > 0)
65 {
66 this.HashCore(buffer, 0, num);
67 totalHashCount += num;
68 }
69 }
70 while (num > 0);
71 this.HashValue = this.HashFinal();
72 byte[] buffer2 = (byte[])this.HashValue.Clone();
73 this.Initialize();
74 return buffer2;
75 }
76 }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-610738/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server 中 ntext 長度如何計算 ?SQLServer
- Lua Table 長度的計算
- javaScript中計算字串MD5JavaScript字串
- 使用PostGIS完成兩點間的河流軌跡及流經長度的計算
- sizeof 和 strlen 計算陣列大小和長度詳解陣列
- C語言 使用Cryptdll計算檔案md5值C語言
- opencv計算曲線長度OpenCV
- 程式碼縮寫和長度值
- Flink流計算中SQL表的概念和原理SQL
- c#相容PHP中的md5C#PHP
- golang 計算最長不重複字串長度Golang字串
- 計算一個檔案的 md5 值很費時間嗎?
- js計算md5JS
- JavaScript計算字串位元組長度JavaScript字串
- C#獲取檔案MD5值方法C#
- 擷取指定長度字串長度程式碼例項字串
- SQL Server 中ntext, text, image長度計算 - datalength 函式SQLServer函式
- C#擷取指定長度中英文字串方法C#字串
- MD5雜湊長度延展攻擊
- java Count如何計算流中的元素Java
- (查詢)找到陣列中的指定值得起始和結束位置陣列
- 圖解計算機中的數值範圍和浮點運算圖解計算機
- MD5值的簡介和檢視
- c語言中計算陣列長度的方法C語言陣列
- C語言如何計算陣列的長度C語言陣列
- 單鞭天線的長度計算方法(轉)
- javascript計算指定日期增加多長時間後的日期JavaScript
- 取字串左邊指定長度的子字串字串
- 取字串右邊指定長度的子字串字串
- SQL Server中生成指定長度的流水號SQLServer
- C# 獲取Excel的指定單元格的值C#Excel
- Linux 中實現按照每一列的類別計算 指定列值的平均數Linux
- C#——Dictionary<TKey, TValue> 計算向量的餘弦值C#
- jquery統計表格指定列的單元格值的和jQuery
- 已計算的關鍵值和限制的關鍵值
- 如何擷取指定長度字串區分漢字和字元字串字元
- JavaScript計算字串的長度區分中英文JavaScript字串
- Android開發:RecyclerView平滑流暢的滑動到指定位置AndroidView