在 C# 中的 VARBINARY 上匹配 SQL 服务器模数
Matching SQL Server Modulo on a VARBINARY in C#
前段时间,我们在 ufn_GroupData 示例函数中实现了这种 Optimizing Protected Indexes 方法的细微变化,从 SQL Server Central 到索引加密数据:
CREATE FUNCTION [dbo].[fncGetBucket]
(
@String NVARCHAR(3500)
)
RETURNS INT
AS
BEGIN
DECLARE @Result INT = NULL;
IF @String IS NOT NULL
SET @Result = HASHBYTES('SHA2_256', @String) % 20000;
RETURN @Result;
END
使用此 UDF 的结果作为“分桶”索引,几百万行愉快地存储在数据库中。
现在我们希望能够在 C# 中生成匹配的存储桶值,上面看似简单的 SQL 并没有说明如何做到这一点。
事实上,我发现很难开始。但我可以说这段代码:
byte[] encoded = SHA256.Create().ComputeHash(Encoding.Unicode.GetBytes(str));
生成与 HASHBYTES 相同的散列,因此我已经完成了第一步。
那么 SQL 实际上用那个模运算符做了什么???
感谢所有帮助!
HASHBYTES('SHA2_256')
returns 一个 32 字节的 ByteArray
内部发生的事情是
cast(HASHBYTES('SHA2_256', @String) as int) % 20000
所以这里有一个整数溢出,被 SQL 服务器优雅地忽略了。
这是未定义的行为并且不容易转换为 C#。
你可以通过取最后 4 个字节和 modulo 那些来实现类似的东西。
这似乎适用于您的 mod 20000。
byte[] encoded = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes("asdf"));
var last4Bytes = encoded.Skip(28).Take(4).Reverse().ToArray();
var myInt = BitConverter.ToInt32(last4Bytes);
var moduloResult = myInt % 20000;
这给了我与
相同的结果
print HASHBYTES('SHA2_256', 'asdf') % 20000
12635
前段时间,我们在 ufn_GroupData 示例函数中实现了这种 Optimizing Protected Indexes 方法的细微变化,从 SQL Server Central 到索引加密数据:
CREATE FUNCTION [dbo].[fncGetBucket]
(
@String NVARCHAR(3500)
)
RETURNS INT
AS
BEGIN
DECLARE @Result INT = NULL;
IF @String IS NOT NULL
SET @Result = HASHBYTES('SHA2_256', @String) % 20000;
RETURN @Result;
END
使用此 UDF 的结果作为“分桶”索引,几百万行愉快地存储在数据库中。
现在我们希望能够在 C# 中生成匹配的存储桶值,上面看似简单的 SQL 并没有说明如何做到这一点。
事实上,我发现很难开始。但我可以说这段代码:
byte[] encoded = SHA256.Create().ComputeHash(Encoding.Unicode.GetBytes(str));
生成与 HASHBYTES 相同的散列,因此我已经完成了第一步。
那么 SQL 实际上用那个模运算符做了什么???
感谢所有帮助!
HASHBYTES('SHA2_256')
returns 一个 32 字节的 ByteArray
内部发生的事情是
cast(HASHBYTES('SHA2_256', @String) as int) % 20000
所以这里有一个整数溢出,被 SQL 服务器优雅地忽略了。
这是未定义的行为并且不容易转换为 C#。
你可以通过取最后 4 个字节和 modulo 那些来实现类似的东西。
这似乎适用于您的 mod 20000。
byte[] encoded = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes("asdf"));
var last4Bytes = encoded.Skip(28).Take(4).Reverse().ToArray();
var myInt = BitConverter.ToInt32(last4Bytes);
var moduloResult = myInt % 20000;
这给了我与
相同的结果print HASHBYTES('SHA2_256', 'asdf') % 20000
12635