Hashing with SHA1 Algorithm in C#
Solution 1
For those who want a "standard" text formatting of the hash, you can use something like the following:
static string Hash(string input)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
var sb = new StringBuilder(hash.Length * 2);
foreach (byte b in hash)
{
// can be "x2" if you want lowercase
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
}
This will produce a hash like 0C2E99D0949684278C30B9369B82638E1CEAD415
.
Or for a code golfed version:
static string Hash(string input)
{
var hash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input));
return string.Concat(hash.Select(b => b.ToString("x2")));
}
For .Net 5 and above, the built-in Convert.ToHexString
gives a nice solution with no compromises:
static string Hash(string input)
{
using var sha1 = SHA1.Create();
return Convert.ToHexString(sha1.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
Solution 2
public string Hash(byte [] temp)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(temp);
return Convert.ToBase64String(hash);
}
}
EDIT:
You could also specify the encoding when converting the byte array to string as follows:
return System.Text.Encoding.UTF8.GetString(hash);
or
return System.Text.Encoding.Unicode.GetString(hash);
Solution 3
This is what I went with. For those of you who want to optimize, check out https://stackoverflow.com/a/624379/991863.
public static string Hash(string stringToHash)
{
using (var sha1 = new SHA1Managed())
{
return BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(stringToHash)));
}
}
Solution 4
Fastest way is this :
public static string GetHash(string input)
{
return string.Join("", (new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input))).Select(x => x.ToString("X2")).ToArray());
}
For Small character output use x2
in replace of of X2
Solution 5
You can "compute the value for the specified byte array" using ComputeHash
:
var hash = sha1.ComputeHash(temp);
If you want to analyse the result in string representation, then you will need to format the bytes using the {0:X2}
format specifier.
![Merve Kaya](https://i.stack.imgur.com/L2He8.jpg?s=256&g=1)
Merve Kaya
Updated on July 08, 2022Comments
-
Merve Kaya almost 2 years
I want to hash given
byte[]
array with usingSHA1
Algorithm with the use ofSHA1Managed
.
Thebyte[]
hash will come from unit test.
Expected hash is0d71ee4472658cd5874c5578410a9d8611fc9aef
(case sensitive).How can I achieve this?
public string Hash(byte [] temp) { using (SHA1Managed sha1 = new SHA1Managed()) { } }
-
Rich about 11 yearsIf they want a hex string then Base64 is probably the wrong choice.
-
John Gathogo about 11 years@Joey: Against the answer given by GrantThomas, the member indicated that they need to return a string
-
John Gathogo about 11 years@MerveKaya: Perhaps you should explain what you mean by "it didnt work". What does the incoming byte array represent? How did you determine "SHA1Managed"-hashing the incoming byte array should give you
0d71ee4472658cd5874c5578410a9d8611fc9aef
as the output? -
Merve Kaya about 11 yearsByte[] hash comes from unit test. In the question they wrote that expected hash is 0d71ee4472658cd5874c5578410a9d8611fc9aef. It comes from unit test
-
John Gathogo about 11 years@MerveKaya: See my update on how to use
Encoding
when converting the hash to a string -
Merve Kaya about 11 yearsNo, unfortunately it failed again
-
sky-dev over 8 yearsIt bugs me that this solution doesn't dispose the SHA1Managed object, because it is marked as Disposable. This post could be handy when optimizing: stackoverflow.com/a/624379/991863
-
kshitij Sabale over 8 years@sky-dev, I usually agree with
IDisposable
, but a quick trip to the reference source shows that nothing interesting happens in.Dispose()
-
sky-dev over 8 yearsYeah, I looked at the Dispose implementation as well. It would just speed GarbageCollection a tad. It probably isn't a big deal in the grand scheme of things.
-
unenthusiasticuser over 7 years@Mitch If it implements the IDisposable interface then what happens in the reference source shouldn't matter. Should they ever change it for any reason such that the .Dispose() call becomes important, your previously working code is now causing a problem. Relying on looking into the bowels of a framework to determine what you can get away with is a path to a maintenance nightmare. I highly suggest following the documentation and correctly handling disposable objects, it'll save you pain in the long term.
-
kshitij Sabale over 7 years@unenthusiastic use, Haha, thanks. I wasn't sure what the purpose of documentation was... (The code in my production applications is the one from the top, but the circumstances of the second make me comfortable enough that it would be equally supportable in all but the tightest loops.
IDisposable
is semi-optional when dealing with non-side-effecting classes.) -
rickythefox about 7 yearsSHA1Managed implements IDisposable, so you would probably want to dispose it when done with it to free up resources.
-
Sam almost 6 yearsI had to use BitConverter.ToString(sha1.ComputeHash(bytes)).Replace("-", "") since I didn't want the dashes introduced by BitConverter. After that it worked like a charm! Thanks!
-
Vince almost 6 yearsjust because something is IDisposable doesn't mean you should call Dispose() on it. source: I've done server-side SharePoint development.
-
aloisdg over 5 yearsFor the second version, you can also replace the select + concat logic with aggregate:
new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input)).Aggregate(string.Empty, (x, y) => x + y.ToString("x2"))
-
ijt almost 4 yearsWhat is the "X2" for?
-
kshitij Sabale almost 4 years@ijt, X2 tells it to use two hexadecimal digits per byte.
x2
means lowercase,X2
is uppercase -
Joey Adams almost 4 yearsIf you need to support machines set to FIPS 140-2 compliance, replace
SHA1Managed
withSHA1CryptoServiceProvider
instead (but keep the rest the same). But to future-proof your code, use a stronger hashing algorithm. Even if your use case is not security-sensitive, these methods can be disabled through system policy. -
kshitij Sabale almost 4 years@JoeyAdams, sure. That is only needed for .Net 2 through .Net 4.7.2, though. .Net 4.8 make the change automatically for you (Managed cryptography classes do not throw a CryptographyException in FIPS mode)
-
Joey Adams almost 4 years@Mitch: Thanks for the refinement. Though this only applies if the application targets .NET 4.8, or if the app config uses
UseLegacyFipsThrow=false
as described in your link. -
quetzalcoatl almost 3 yearsIt's not the fastest way, it's merely packed into a single line.
-
alireza amini almost 3 years@quetzalcoatl well, yeah :)