48e323ccc0ee82c09c5edeebce064c710838415e
[mono.git] / mcs / class / corlib / System.Security.Cryptography / HashAlgorithm.cs
1 //
2 // System.Security.Cryptography HashAlgorithm Class implementation
3 //
4 // Authors:
5 //      Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
6 //      Sebastien Pouliot (sebastien@ximian.com)
7 //
8 // Copyright 2001 by Matthew S. Ford.
9 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
10 // (C) 2004 Novell (http://www.novell.com)
11 //
12
13 using System.Globalization;
14 using System.IO;
15
16 namespace System.Security.Cryptography {
17
18         public abstract class HashAlgorithm : ICryptoTransform {
19
20                 protected byte[] HashValue;
21                 protected int HashSizeValue;
22                 protected int State;
23                 private bool disposed;
24
25                 protected HashAlgorithm () 
26                 {
27                         disposed = false;
28                 }
29
30                 public virtual bool CanTransformMultipleBlocks {
31                         get { return true; }
32                 }
33
34                 public virtual bool CanReuseTransform {
35                         get { return true; }
36                 }
37
38                 public void Clear () 
39                 {
40                         // same as System.IDisposable.Dispose() which is documented
41                         Dispose (true);
42                 }
43
44                 public byte[] ComputeHash (byte[] input) 
45                 {
46                         return ComputeHash (input, 0, input.Length);
47                 }
48
49                 public byte[] ComputeHash (byte[] buffer, int offset, int count) 
50                 {
51                         if (disposed)
52                                 throw new ObjectDisposedException ("HashAlgorithm");
53
54                         HashCore (buffer, offset, count);
55                         HashValue = HashFinal ();
56                         Initialize ();
57                         
58                         return HashValue;
59                 }
60
61                 public byte[] ComputeHash (Stream inputStream) 
62                 {
63                         // don't read stream unless object is ready to use
64                         if (disposed)
65                                 throw new ObjectDisposedException ("HashAlgorithm");
66
67                         byte[] buffer = new byte [4096];
68                         int len = inputStream.Read (buffer, 0, 4096);
69                         while (len > 0) {
70                                 HashCore (buffer, 0, len);
71                                 len = inputStream.Read (buffer, 0, 4096);
72                         }
73                         HashValue = HashFinal ();
74                         Initialize ();
75                         return HashValue;
76                 }
77         
78                 public static HashAlgorithm Create () 
79                 {
80                         return Create ("System.Security.Cryptography.HashAlgorithm");
81                 }
82         
83                 public static HashAlgorithm Create (string hashName)
84                 {
85                         return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
86                 }
87         
88                 public virtual byte[] Hash {
89                         get { 
90                                 if (HashValue == null) {
91                                         throw new CryptographicUnexpectedOperationException (
92                                                 Locale.GetText ("No hash value computed."));
93                                 }
94                                 return HashValue; 
95                         }
96                 }
97         
98                 protected abstract void HashCore (byte[] rgb, int start, int size);
99
100                 protected abstract byte[] HashFinal ();
101
102                 public virtual int HashSize {
103                         get { return HashSizeValue; }
104                 }
105         
106                 public abstract void Initialize ();
107
108                 protected virtual void Dispose (bool disposing)
109                 {
110                         disposed = true;
111                 }
112         
113                 public virtual int InputBlockSize {
114                         get { return 1; }
115                 }
116         
117                 public virtual int OutputBlockSize {
118                         get { return 1; }
119                 }
120
121                 void IDisposable.Dispose () 
122                 {
123                         Dispose (true);
124                         GC.SuppressFinalize (this);  // Finalization is now unnecessary
125                 }
126                 
127                 public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) 
128                 {
129                         Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
130                         HashCore (inputBuffer, inputOffset, inputCount);
131
132                         return inputCount;
133                 }
134         
135                 public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) 
136                 {
137                         byte[] outputBuffer = new byte [inputCount];
138                         
139                         Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
140                         
141                         HashCore (inputBuffer, inputOffset, inputCount);
142                         HashValue = HashFinal ();
143                         Initialize ();
144                         
145                         return outputBuffer;
146                 }
147         }
148 }