Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SQL Server哈希字节和扩展Ascii_C#_Sql Server_Hash_Ascii_Md5 - Fatal编程技术网

C# SQL Server哈希字节和扩展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

我正在Oracle和SQL Server之间进行ETL过程(无主键->无事务复制),并使用MD5哈希检测源数据库和目标数据库之间的差异

对于那些数据包含在前127个ASCII字符中的记录,这种方法非常有效。但是,如果存在任何“扩展ascii”*字符,例如
½
°
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'°)的字符串哈希值将为您提供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);
  }
}