C# SQL Server哈希字节和扩展Ascii
我正在Oracle和SQL Server之间进行ETL过程(无主键->无事务复制),并使用MD5哈希检测源数据库和目标数据库之间的差异 对于那些数据包含在前127个ASCII字符中的记录,这种方法非常有效。但是,如果存在任何“扩展ascii”*字符,例如C# SQL Server哈希字节和扩展Ascii,c#,sql-server,hash,ascii,md5,C#,Sql Server,Hash,Ascii,Md5,我正在Oracle和SQL Server之间进行ETL过程(无主键->无事务复制),并使用MD5哈希检测源数据库和目标数据库之间的差异 对于那些数据包含在前127个ASCII字符中的记录,这种方法非常有效。但是,如果存在任何“扩展ascii”*字符,例如½、°或)SQL Server的HASHBYTES函数以非标准方式对这些字符进行散列(即不同于Oracle的DBMS\u CRYPTO.Hash、.Net加密库等) 因此,当我在Oracle中运行此功能时: select rawtohex( DB
½
、°
或)
SQL Server的HASHBYTES
函数以非标准方式对这些字符进行散列(即不同于Oracle的DBMS\u CRYPTO.Hash
、.Net加密库等)
因此,当我在Oracle中运行此功能时:
select rawtohex(
DBMS_CRYPTO.Hash (
UTL_I18N.STRING_TO_RAW ('°', 'AL32UTF8'),
2)
) from dual;
我得到:4723EB5AA8B0CD28C7E09433839B8FAE
在SQL Server中运行时:
SELECT HASHBYTES('md5', '°');
我得到:EC655B6DA8B9264A7C7C5E1A7064FA7
当我运行这个C代码时:
我得到的4723EB5AA8B0CD28C7E09433839B8FAE
与Oracle和我使用的所有在线工具相同
是否有任何基于SQL的解决方案来解决此问题,或者是否需要创建CLR存储过程并在其中散列数据
*我意识到这个术语有点争议到目前为止,MS SQL Server中还没有UTF-8支持。因此,在将源字符串切换到最常见的分母(在本例中可能是UTF-16)之前,您的哈希值将始终不同。我决定通过实现使用.Net加密库的CLR存储过程来绕过SQL Server对扩展ASCII的处理:
using System;
using System.Security.Cryptography;
using System.Text;
using Microsoft.SqlServer.Server;
public class Functions
{
[SqlFunction]
public static string GetMD5Hash (string input)
{
var encodedPassword = new UTF8Encoding().GetBytes(input);
var hash = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(encodedPassword);
return BitConverter.ToString(hash).Replace("-", string.Empty);
}
}
MD5是MD5,如果输出不同,输入也不同-如果输入看起来相同,那么这是与输入的二进制解释相关的编码问题。您能否显示此类HASHBYTES()调用的输入和输出以及预期结果?SQL Server将返回解释为ISO-8859-1、
HASHBYTES('md5',N'°)的字符串哈希值如果您可以在Oracle中使用UTF16结果,则代码>将为您提供UTF16结果?可能重复
using System;
using System.Security.Cryptography;
using System.Text;
using Microsoft.SqlServer.Server;
public class Functions
{
[SqlFunction]
public static string GetMD5Hash (string input)
{
var encodedPassword = new UTF8Encoding().GetBytes(input);
var hash = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(encodedPassword);
return BitConverter.ToString(hash).Replace("-", string.Empty);
}
}