@@ -19,6 +19,16 @@ namespace System.Security.Cryptography
1919
2020 public abstract class MD5 : HashAlgorithm
2121 {
22+ private sealed class HashTrait : IHashStatic
23+ {
24+ static int IHashStatic . HashSizeInBytes => HashSizeInBytes ;
25+ static string IHashStatic . HashAlgorithmName => HashAlgorithmNames . MD5 ;
26+
27+ // Even though MD5 is not supported on browser, we return true and let it act as an unknown algorithm
28+ // instead of an unsupported algorithm.
29+ static bool IHashStatic . IsSupported => true ;
30+ }
31+
2232 /// <summary>
2333 /// The hash size produced by the MD5 algorithm, in bits.
2434 /// </summary>
@@ -50,28 +60,15 @@ protected MD5()
5060 /// <paramref name="source" /> is <see langword="null" />.
5161 /// </exception>
5262 [ UnsupportedOSPlatform ( "browser" ) ]
53- public static byte [ ] HashData ( byte [ ] source )
54- {
55- ArgumentNullException . ThrowIfNull ( source ) ;
56-
57- return HashData ( new ReadOnlySpan < byte > ( source ) ) ;
58- }
63+ public static byte [ ] HashData ( byte [ ] source ) => HashStatic < HashTrait > . HashData ( source ) ;
5964
6065 /// <summary>
6166 /// Computes the hash of data using the MD5 algorithm.
6267 /// </summary>
6368 /// <param name="source">The data to hash.</param>
6469 /// <returns>The hash of the data.</returns>
6570 [ UnsupportedOSPlatform ( "browser" ) ]
66- public static byte [ ] HashData ( ReadOnlySpan < byte > source )
67- {
68- byte [ ] buffer = GC . AllocateUninitializedArray < byte > ( HashSizeInBytes ) ;
69-
70- int written = HashData ( source , buffer . AsSpan ( ) ) ;
71- Debug . Assert ( written == buffer . Length ) ;
72-
73- return buffer ;
74- }
71+ public static byte [ ] HashData ( ReadOnlySpan < byte > source ) => HashStatic < HashTrait > . HashData ( source ) ;
7572
7673 /// <summary>
7774 /// Computes the hash of data using the MD5 algorithm.
@@ -86,10 +83,7 @@ public static byte[] HashData(ReadOnlySpan<byte> source)
8683 [ UnsupportedOSPlatform ( "browser" ) ]
8784 public static int HashData ( ReadOnlySpan < byte > source , Span < byte > destination )
8885 {
89- if ( ! TryHashData ( source , destination , out int bytesWritten ) )
90- throw new ArgumentException ( SR . Argument_DestinationTooShort , nameof ( destination ) ) ;
91-
92- return bytesWritten ;
86+ return HashStatic < HashTrait > . HashData ( source , destination ) ;
9387 }
9488
9589 /// <summary>
@@ -107,16 +101,7 @@ public static int HashData(ReadOnlySpan<byte> source, Span<byte> destination)
107101 [ UnsupportedOSPlatform ( "browser" ) ]
108102 public static bool TryHashData ( ReadOnlySpan < byte > source , Span < byte > destination , out int bytesWritten )
109103 {
110- if ( destination . Length < HashSizeInBytes )
111- {
112- bytesWritten = 0 ;
113- return false ;
114- }
115-
116- bytesWritten = HashProviderDispenser . OneShotHashProvider . HashData ( HashAlgorithmNames . MD5 , source , destination ) ;
117- Debug . Assert ( bytesWritten == HashSizeInBytes ) ;
118-
119- return true ;
104+ return HashStatic < HashTrait > . TryHashData ( source , destination , out bytesWritten ) ;
120105 }
121106
122107 /// <summary>
@@ -141,15 +126,7 @@ public static bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination
141126 [ UnsupportedOSPlatform ( "browser" ) ]
142127 public static int HashData ( Stream source , Span < byte > destination )
143128 {
144- ArgumentNullException . ThrowIfNull ( source ) ;
145-
146- if ( destination . Length < HashSizeInBytes )
147- throw new ArgumentException ( SR . Argument_DestinationTooShort , nameof ( destination ) ) ;
148-
149- if ( ! source . CanRead )
150- throw new ArgumentException ( SR . Argument_StreamNotReadable , nameof ( source ) ) ;
151-
152- return LiteHashProvider . HashStream ( HashAlgorithmNames . MD5 , source , destination ) ;
129+ return HashStatic < HashTrait > . HashData ( source , destination ) ;
153130 }
154131
155132 /// <summary>
@@ -164,15 +141,7 @@ public static int HashData(Stream source, Span<byte> destination)
164141 /// <paramref name="source" /> does not support reading.
165142 /// </exception>
166143 [ UnsupportedOSPlatform ( "browser" ) ]
167- public static byte [ ] HashData ( Stream source )
168- {
169- ArgumentNullException . ThrowIfNull ( source ) ;
170-
171- if ( ! source . CanRead )
172- throw new ArgumentException ( SR . Argument_StreamNotReadable , nameof ( source ) ) ;
173-
174- return LiteHashProvider . HashStream ( HashAlgorithmNames . MD5 , HashSizeInBytes , source ) ;
175- }
144+ public static byte [ ] HashData ( Stream source ) => HashStatic < HashTrait > . HashData ( source ) ;
176145
177146 /// <summary>
178147 /// Asynchronously computes the hash of a stream using the MD5 algorithm.
@@ -192,12 +161,7 @@ public static byte[] HashData(Stream source)
192161 [ UnsupportedOSPlatform ( "browser" ) ]
193162 public static ValueTask < byte [ ] > HashDataAsync ( Stream source , CancellationToken cancellationToken = default )
194163 {
195- ArgumentNullException . ThrowIfNull ( source ) ;
196-
197- if ( ! source . CanRead )
198- throw new ArgumentException ( SR . Argument_StreamNotReadable , nameof ( source ) ) ;
199-
200- return LiteHashProvider . HashStreamAsync ( HashAlgorithmNames . MD5 , source , cancellationToken ) ;
164+ return HashStatic < HashTrait > . HashDataAsync ( source , cancellationToken ) ;
201165 }
202166
203167 /// <summary>
@@ -229,19 +193,7 @@ public static ValueTask<int> HashDataAsync(
229193 Memory < byte > destination ,
230194 CancellationToken cancellationToken = default )
231195 {
232- ArgumentNullException . ThrowIfNull ( source ) ;
233-
234- if ( destination . Length < HashSizeInBytes )
235- throw new ArgumentException ( SR . Argument_DestinationTooShort , nameof ( destination ) ) ;
236-
237- if ( ! source . CanRead )
238- throw new ArgumentException ( SR . Argument_StreamNotReadable , nameof ( source ) ) ;
239-
240- return LiteHashProvider . HashStreamAsync (
241- HashAlgorithmNames . MD5 ,
242- source ,
243- destination ,
244- cancellationToken ) ;
196+ return HashStatic < HashTrait > . HashDataAsync ( source , destination , cancellationToken ) ;
245197 }
246198
247199 private sealed class Implementation : MD5
0 commit comments