Equivalent of SQL Server HASHBYTES('sha1',

2019-09-02 07:55发布

问题:

I am trying to migrate some stored procedures to C# code.

I am trying to find what is equivalent for this function HASHBYTES('sha1', password) in C# code.

Generated values of HASHBYTES('sha1', "Glenw00d@3") in T-SQL is "зmG>”TëÏåÈ“ÇOó26¥"

Does C# have an equivalent of this T-SQL function or not?

UPDATE:

I tried to use this code:

  public static class SHA1Util
  {
        /// <summary>
        /// Compute hash for string encoded as UTF8
        /// </summary>
        /// <param name="s">String to be hashed</param>
        /// <returns>40-character hex string</returns>
        public static string SHA1HashStringForUTF8String(string s)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(s);

            var sha1 = SHA1.Create();
            byte[] hashBytes = sha1.ComputeHash(bytes);

            return HexStringFromBytes(hashBytes);
        }

        /// <summary>
        /// Convert an array of bytes to a string of hex digits
        /// </summary>
        /// <param name="bytes">array of bytes</param>
        /// <returns>String of hex digits</returns>
        public static string HexStringFromBytes(byte[] bytes)
        {
            var sb = new StringBuilder();
            foreach (byte b in bytes)
            {
                var hex = b.ToString("x2");
                sb.Append(hex);
            }
            return sb.ToString();
        }
    }

but it returns different results.

var hashString = SHA1Util.SHA1HashStringForUTF8String("Glenw00d@@3");//result for this was d0b76d473e945417ebcf18e5c893c74ff33236a5

回答1:

Unless you change the default endoding, normally SQL Server uses Windows-1252 for VARCHAR().

private static readonly Encoding Encoding1252 = Encoding.GetEncoding(1252);

/// <summary>
/// Compute hash for string encoded as Windows-1252
/// </summary>
/// <param name="s">String to be hashed</param>
/// <returns>40-character hex string</returns>
public static string SHA1HashStringForDefaultString(string s)
{
    byte[] bytes = Encoding1252.GetBytes(s);

Found the problem:

You are hashing two different strings

HASHBYTES('sha1', "Glenw00d@3") 

and

SHA1Util.SHA1HashStringForUTF8String("Glenw00d@@3")

See the @/@@?

Now, for the encoding, I'll say that it is Windows-1252. But you can check with

Select TABLE_NAME, COLUMN_NAME, Columns.COLLATION_NAME From INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Yourtable'

If the collation for your column contains the CP1 then it is Windows-1252.

For the output... If you want a string, replace the return with:

return Encoding1252.GetString(hashBytes);

For Glenw00d@@3 the hash is: 0LdtRz6UVBfrzxjlyJPHT/MyNqU=

if you want an hex string, leave the return as is,

For Glenw00d@@3 the hash is: d0b76d473e945417ebcf18e5c893c74ff33236a5

if you want it base64:

return Convert.ToBase64String(hashBytes);

For Glenw00d@@3 the hash is: 0LdtRz6UVBfrzxjlyJPHT/MyNqU=