c# – 基于.net的SQL CLR函数ComputeHash不与Cyrrilic一起使用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 基于.net的SQL CLR函数ComputeHash不与Cyrrilic一起使用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2567字,纯文字阅读大概需要4分钟。
内容图文
![c# – 基于.net的SQL CLR函数ComputeHash不与Cyrrilic一起使用](/upload/InfoBanner/zyjiaocheng/909/40c3e51bb2684e33a75b418dd1828f8e.jpg)
我编写了以下SQL CLR函数,以便散列大于8000字节的字符串值(T-SQL内置HASHBYTES函数的输入值的限制):
[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
public static SqlBinary HashBytes(SqlString algorithm, SqlString value)
{
HashAlgorithm algorithmType = HashAlgorithm.Create(algorithm.Value);
if (algorithmType == null || value.IsNull)
{
return new SqlBinary();
}
else
{
byte[] bytes = Encoding.UTF8.GetBytes(value.Value);
return new SqlBinary(algorithmType.ComputeHash(bytes));
}
}
它适用于拉丁字符串.例如,以下哈希值是相同的:
SELECT dbo.fn_Utils_GetHashBytes ('MD5', 'test'); -- 0x098F6BCD4621D373CADE4E832627B4F6
SELECT HASHBYTES ('MD5', 'test'); -- 0x098F6BCD4621D373CADE4E832627B4F6
问题是它不适用于西里尔字符串.例如:
SELECT dbo.fn_Utils_GetHashBytes ('MD5 ', N'даровете на влъхвите') -- NULL
SELECT HashBytes ('MD5 ',N'даровете на влъхвите') -- 0x838B1B625A6074B2BE55CDB7FCEA2832
SELECT dbo.fn_Utils_GetHashBytes ('SHA256', N'даровете на влъхвите') -- 0xA1D65374A0B954F8291E00BC3DD9DF655D8A4A6BF127CFB15BBE794D2A098844
SELECT HashBytes ('SHA2_256',N'даровете на влъхвите') -- 0x375F6993E0ECE1864336E565C8E14848F2A4BAFCF60BC0C8F5636101DD15B25A
我为MD5获取NULL,但如果代码作为控制台应用程序执行,则代码返回值.谁能说出我做错了什么?
另外,我从here获得了功能,其中一条评论说:
Careful with CLR SP parameters being silently truncated to 8000 bytes
– I had to tag the parameter with [SqlFacet(MaxSize = -1)] otherwise bytes after the 8000th would simply be ignored!
但我测试了这个,它工作正常.例如,如果我生成一个8000字节字符串的散列和相同字符串的第二个散列加一个符号,我得到的散列是不同的.
DECLARE @A VARCHAR(MAX) = '8000 bytes string...'
DECLARE @B VARCHAR(MAX) = @A + '1'
SELECT LEN(@A), LEN(@B)
SELECT IIF(dbo.fn_Utils_GetHashBytes ('MD5', @A + '1') = dbo.fn_Utils_GetHashBytes ('MD5', @B), 1, 0) -- 0
我应该担心吗?
解决方法:
Encoding.UTF8.GetBytes(...)
SQL Server没有UTF-8的概念.使用UCS-2(UTF-16)或ASCII.使用的编码必须与您传递给HASHBYTES的编码相匹配.您可以很容易地看到HASHBYTES将以不同的方式散列VARCHAR与NVARCHAR:
select HASHBYTES('MD5', 'Foo') -- 0x1356C67D7AD1638D816BFB822DD2C25D
select HASHBYTES('MD5', N'Foo') -- 0xB25FF0AD90D09D395090E8A29FF4C63C
最好的方法是更改??SQLCLR函数以接受字节,而不是字符串,并在调用者中处理转换为VARBINARY.
SELECT dbo.fn_Utils_GetHashBytes ('MD5', CAST(N'даровете на влъхвите' AS VARBINARY(MAX));
仅供参考,SQL Server 2016已经解除了对HASHBYTES的8000字节限制:
For SQL Server 2014 and earlier, allowed input values are limited to 8000 bytes.
内容总结
以上是互联网集市为您收集整理的c# – 基于.net的SQL CLR函数ComputeHash不与Cyrrilic一起使用全部内容,希望文章能够帮你解决c# – 基于.net的SQL CLR函数ComputeHash不与Cyrrilic一起使用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。