次のC#コードを使用して、文字列からMD5ハッシュを計算します。うまく機能し、次のような32文字の16進文字列を生成します。900150983cd24fb0d6963f7d28e17f72
string sSourceData;
byte[] tmpSource;
byte[] tmpHash;
sSourceData = "MySourceData";
//Create a byte array from source data.
tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
// and then convert tmpHash to string...
このようなコードを使用して、16文字の16進数文字列(または12文字の文字列)を生成する方法はありますか? 32文字の16進文字列は良いですが、顧客がコードを入力するのは退屈だと思います!
MSDN に従って
MD5を作成します。
public static string CreateMD5(string input)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// Convert the byte array to hexadecimal string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString();
}
}
// given, a password in a string
string password = @"1234abcd";
// byte array representation of that string
byte[] encodedPassword = new UTF8Encoding().GetBytes(password);
// need MD5 to calculate the hash
byte[] hash = ((HashAlgorithm) CryptoConfig.CreateFromName("MD5")).ComputeHash(encodedPassword);
// string representation (similar to UNIX format)
string encoded = BitConverter.ToString(hash)
// without dashes
.Replace("-", string.Empty)
// make lowercase
.ToLower();
// encoded contains the hash you want
Convert.ToBase64String
を使用して、MD5の16バイト出力を〜24文字の文字列に変換できます。セキュリティを低下させることなく、少し良くなりました。 (例としてj9JIbSY8HuT89/pwdC8jlw==
)
LINQを使用してMD5ハッシュの文字列表現を作成しようとしていましたが、答えはどれもLINQソリューションではなかったため、これを利用可能なソリューションのバイキングに追加しました。
string result;
using (MD5 hash = MD5.Create())
{
result = String.Join
(
"",
from ba in hash.ComputeHash
(
Encoding.UTF8.GetBytes(observedText)
)
select ba.ToString("x2")
);
}
達成しようとしていることに完全に依存します。技術的には、MD5ハッシュの結果から最初の12文字を取得できますが、MD5の仕様では32文字のハッシュを生成します。
ハッシュのサイズを小さくすると、セキュリティが低下し、衝突やシステムが破損する可能性が高くなります。
おそらく、あなたが達成しようとしていることについて私たちにもっと知らせてくれれば、私たちはもっと支援できるかもしれません。
文字列とファイルストリームをサポートします。
例
string hashString = EasyMD5.Hash("My String");
string hashFile = EasyMD5.Hash(System.IO.File.OpenRead("myFile.txt"));
-
class EasyMD5
{
private static string GetMd5Hash(byte[] data)
{
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
sBuilder.Append(data[i].ToString("x2"));
return sBuilder.ToString();
}
private static bool VerifyMd5Hash(byte[] data, string hash)
{
return 0 == StringComparer.OrdinalIgnoreCase.Compare(GetMd5Hash(data), hash);
}
public static string Hash(string data)
{
using (var md5 = MD5.Create())
return GetMd5Hash(md5.ComputeHash(Encoding.UTF8.GetBytes(data)));
}
public static string Hash(FileStream data)
{
using (var md5 = MD5.Create())
return GetMd5Hash(md5.ComputeHash(data));
}
public static bool Verify(string data, string hash)
{
using (var md5 = MD5.Create())
return VerifyMd5Hash(md5.ComputeHash(Encoding.UTF8.GetBytes(data)), hash);
}
public static bool Verify(FileStream data, string hash)
{
using (var md5 = MD5.Create())
return VerifyMd5Hash(md5.ComputeHash(data), hash);
}
}
文字列MD5でUTF-8エンコーディングを使用する方が良いと思います。
public static string MD5(this string s)
{
using (var provider = System.Security.Cryptography.MD5.Create())
{
StringBuilder builder = new StringBuilder();
foreach (byte b in provider.ComputeHash(Encoding.UTF8.GetBytes(s)))
builder.Append(b.ToString("x2").ToLower());
return builder.ToString();
}
}
MD5ハッシュは128ビットであるため、32文字未満の16進数で表すことはできません...
System.Text.StringBuilder hash = new System.Text.StringBuilder();
System.Security.Cryptography.MD5CryptoServiceProvider md5provider = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bytes = md5provider.ComputeHash(new System.Text.UTF8Encoding().GetBytes(YourEntryString));
for (int i = 0; i < bytes.Length; i++)
{
hash.Append(bytes[i].ToString("x2")); //lowerCase; X2 if uppercase desired
}
return hash.ToString();
.NET Core 2.1以降の既存の回答のより高速な代替手段:
public static string CreateMD5(string s)
{
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
var encoding = Encoding.ASCII;
var data = encoding.GetBytes(s);
Span<byte> hashBytes = stackalloc byte[16];
md5.TryComputeHash(data, hashBytes, out int written);
if(written != hashBytes.Length)
throw new OverflowException();
Span<char> stringBuffer = stackalloc char[32];
for (int i = 0; i < hashBytes.Length; i++)
{
hashBytes[i].TryFormat(stringBuffer.Slice(2 * i), out _, "x2");
}
return new string(stringBuffer);
}
}
文字列が十分に小さく、encoding.GetBytesを安全でないint GetBytes(ReadOnlySpan chars、Span bytes)代替に置き換えることが確実な場合は、さらに最適化できます。
https://docs.Microsoft.com/en-us/dotnet/api/system.security.cryptography.md5?view=netframework-4.7.2
using System;
using System.Security.Cryptography;
using System.Text;
static string GetMd5Hash(string input)
{
using (MD5 md5Hash = MD5.Create())
{
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
}
// Verify a hash against a string.
static bool VerifyMd5Hash(string input, string hash)
{
// Hash the input.
string hashOfInput = GetMd5Hash(input);
// Create a StringComparer an compare the hashes.
StringComparer comparer = StringComparer.OrdinalIgnoreCase;
return 0 == comparer.Compare(hashOfInput, hash);
}
StringBuilder sb= new StringBuilder();
for (int i = 0; i < tmpHash.Length; i++)
{
sb.Append(tmpHash[i].ToString("x2"));
}
このソリューションにはc#7.2が必要で、Span<T>
を利用します。入力サイズに関係なく、これは固定量のメモリを割り当て、受け入れられた回答よりも高速です。必要に応じて、.Replace("-", string.Empty).ToLowerInvariant()
を呼び出して結果をフォーマットする必要があることに注意してください。
public static string CreateMD5(ReadOnlySpan<char> input)
{
var encoding = System.Text.Encoding.UTF8;
var inputByteCount = encoding.GetByteCount(input);
using (var md5 = System.Security.Cryptography.MD5.Create())
{
Span<byte> bytes = stackalloc byte[inputByteCount];
Span<byte> destination = stackalloc byte[md5.HashSize / 8];
encoding.GetBytes(input, bytes);
// checking the result is not required because this only returns false if "(destination.Length < HashSizeValue/8)", which is never true in this case
md5.TryComputeHash(bytes, destination, out int _bytesWritten);
return BitConverter.ToString(destination.ToArray());
}
}