我有一个char(32)类型的列,我想存储一个MD5哈希键。问题是我使用SQL来使用HashBytes()函数更新现有记录,该函数创建了像
这样的值:›=k! ©úw"5Ýâ‘<\
但是当我通过.NET进行插入时,它会以
的形式出现3A9B3D6B2120A9FA772235DDE2913C5C
我需要做些什么来使这些匹配?是编码吗?
答案 0 :(得分:5)
HashKey不是SQL函数,你的意思是HASHBYTES
吗?一些实际代码会有所帮助。 SQL似乎正在计算原始二进制哈希并将其显示为ASCII字符。
.NET正在计算哈希值,然后将其转换为十六进制(或者它出现)。 CHAR(32)不是存储原始二进制数据的好方法,您可能希望使用BINARY类型。
SQL中的示例:
SELECT SUBSTRING(sys.fn_varbintohexstr(HASHBYTES('MD5',0x2040)),3, 32)
.NET中的一个例子:
using (MD5 md5 = MD5.Create())
{
var data = new byte[] { 0x20, 0x40 };
var hashed = md5.ComputeHash(data);
var hexHash = BitConverter.ToString(hashed).Replace("-", "");
Console.Out.WriteLine("hexHash = {0}", hexHash);
}
这些都会产生相同的值。 (其中0x2040是样本数据)。
您可以将十六进制数据存储为CHAR(32),也可以存储为BINARY(16)。存储二进制数据的空间效率是将其存储为十六进制的两倍。你不应该做的是将二进制数据存储为CHAR(16)。
答案 1 :(得分:0)
当我通过.NET进行插入时,你不清楚你是什么意思 - 但你不应该只是以原始形式存储二进制数据,因为它看起来像你的使用HashKey()
。 (顺便说一下你的意思是HashKey
吗?我找不到它的参考,但有HashBytes
...)
两个常见选项是将原始二进制数据编码为十六进制 - 它看起来像你在第二种情况下所做的那样 - 或者使用base64。无论哪种方式都应该很容易从.NET(Base64使用Convert.ToBase64String
稍微容易一点),你可能只需要找到等效的SQL Server函数。
答案 2 :(得分:0)
MD5通常以十六进制编码方式存储。我猜你的hashkey()SQL函数不是十六进制编码MD5哈希,而只是返回表示哈希的ASCII字符。但是你的.NET方法是HEX编码。如果将MD5散列一直存储为HEX(或者不是 - 由您决定,但通常存储为HEX),那么两者之间的结果应始终保持一致。
例如,SQL哈希中的:符号是从HashKey()返回的第一个字符。在.NET方法中,前2个字符是3A。 31是十进制的51。 ASCII码51是冒号(:)字符。同样,您可以通过其他角色工作,并进行十六进制转换。
请参阅任何ASCII代码表以供参考,即http://www.asciitable.com/