Вычислить хэш MD5 из строки

Я использую следующий код С# для вычисления хеша MD5 из строки. Он хорошо работает и генерирует шестнадцатеричную строку из 32 символов, например: 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 символов (или 12-символьной строки)? 32-символьная шестнадцатеричная строка хороша, но я думаю, что для пользователя будет скучно вводить код!

Ответ 1

Согласно 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();
        }
    }

Ответ 2

// 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

Ответ 3

В зависимости от цели, которую вы пытаетесь достичь. Технически вы могли бы просто взять первые 12 символов из результата хеша MD5, но спецификация MD5 должна генерировать 32 char.

Уменьшение размера хэша снижает безопасность и увеличивает вероятность столкновений и разрушения системы.

Возможно, если вы сообщите нам больше о том, чего вы пытаетесь достичь, мы сможем помочь больше.

Ответ 4

Вы можете использовать Convert.ToBase64String для преобразования 16-байтового вывода MD5 в строку ~ 24 char. Немного лучше без снижения безопасности. (j9JIbSY8HuT89/pwdC8jlw== для вашего примера)

Ответ 5

пытался создать строковое представление хеша MD5 с использованием LINQ, однако ни один из ответов не был решением LINQ, поэтому добавив его к smorgasbord доступных решений.

string result;
using (MD5 hash = MD5.Create())
{
    result = String.Join
    (
        "",
        from ba in hash.ComputeHash
        (
            Encoding.UTF8.GetBytes(observedText)
        ) 
        select ba.ToString("x2")
    );
}

Ответ 6

Поддержка строки и файлового потока.

Примеры

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);
            }
        }

Ответ 7

Хэш MD5 составляет 128 бит, поэтому вы не можете представить его в шестнадцатеричном формате с менее чем 32 символами...

Ответ 8

Я полагаю, что лучше использовать кодировку UTF-8 в строке MD5.

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();
    }
}

Ответ 9

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();

Ответ 10

StringBuilder sb= new StringBuilder();
for (int i = 0; i < tmpHash.Length; i++)
{
   sb.Append(tmpHash[i].ToString("x2"));
}

Ответ 11

Это решение требует С# 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());
    }
}

Ответ 12

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);

            }

Ответ 13

Более быстрая альтернатива существующего ответа для .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).