Java 如何生成匹配的MD5哈希:SQL Server nvarchar字段与ColdFusion

Java 如何生成匹配的MD5哈希:SQL Server nvarchar字段与ColdFusion,java,sql-server,coldfusion,Java,Sql Server,Coldfusion,我试图找出如何在SQL Server和ColdFusion之间生成匹配的MD 5哈希值。根本原因似乎是SQL Server字段是nvarchar数据类型,这似乎意味着我需要对我将在ColdFusion或Java中散列的字符串进行编码,以使其匹配,但我无法找到它。要清楚,如果这是一个SQL Server varchar字段,则一切正常 以下是我正在尝试的代码: <cfset stringToHash = "Hello world!"> <cfquery name="sqlser

我试图找出如何在SQL Server和ColdFusion之间生成匹配的MD 5哈希值。根本原因似乎是SQL Server字段是
nvarchar
数据类型,这似乎意味着我需要对我将在ColdFusion或Java中散列的字符串进行编码,以使其匹配,但我无法找到它。要清楚,如果这是一个SQL Server varchar字段,则一切正常

以下是我正在尝试的代码:

<cfset stringToHash = "Hello world!">

<cfquery name="sqlserver" datasource="#mySqlServerDSN#">
    SELECT RIGHT( 
    master.dbo.fn_varbintohexstr( 
        HashBytes( 
            'MD5', 
            CAST(<cfqueryparam value="#stringToHash#" cfsqltype="cf_sql_varchar">  AS nvarchar(max))      
        ) 
    ) 
   , 32) AS HASHED
</cfquery>

<cfoutput>
<pre>
CF UFT-8:   #hash(stringToHash, 'MD5', 'UTF-8')#
CF UFT-16:  #hash(stringToHash, 'MD5', 'UTF-16')#
SQL Server: #sqlserver.hashed#
</pre>
</cfoutput>

所以我猜我需要将传递给
hash()
的最后一个参数更改为不同的编码,但我无法理解。我也将这个问题标记为Java,因为我非常乐意用Java语言回答

我很好奇为什么您的sql server专栏是nvarchar;对于散列来说这是不必要的。nvarchar用于存储扩展字符集,您不应该从哈希函数中获取扩展字符集

不管怎样,我尝试了CF9中所有可用的哈希算法,但没有一个生成您要查找的哈希


除非由于某些尚未解释的原因需要将列设置为nvarchar,否则为什么不将其更改为varchar?

我很好奇为什么sql server列是nvarchar;对于散列来说这是不必要的。nvarchar用于存储扩展字符集,您不应该从哈希函数中获取扩展字符集

不管怎样,我尝试了CF9中所有可用的哈希算法,但没有一个生成您要查找的哈希


除非您需要将列设置为nvarchar,因为您还没有解释过的原因,为什么不将其更改为varchar?

我认为这不是CF哈希,因为如果您将CF与Java进行比较,它们会创建相同的哈希。我的框上的CF和Java输出“65a8e27d8879283831b664bd8b7f0ad4”和我将强制转换更改为varchar时的SQL哈希匹配(32)

在过去,当我需要进行任何类型的散列创建和比较时,我创建了一个返回字符串的服务,这样您就不必担心跨平台的算法问题。您也可以让sql为您完成这一切,但是您的业务逻辑在错误的层中,但每个层都有自己的逻辑

<cfscript>
    helloWorld = "Hello, World!";
    utf8HashCF = lcase(hash(helloWorld, 'MD5', 'UTF-16LE'));
</cfscript>
<cfoutput>
    #utf8HashCF# <br />
</cfoutput>

helloWorld=“你好,世界!”;
javaString=CreateObject(“java”,“java.lang.String”).Init(helloWorld);
javaHash=CreateObject(“java”、“java.security.MessageDigest”).getInstance(“MD5”);
javaHash.reset();
update(javaString.getBytes(“UTF-8”)、0、javaString.length();
javaBigInt=CreateObject(“java”,“java.math.biginger”).Init(1,javaHash.digest());
utf8HashCF=lcase(hash(helloWorld,'MD5','UTF-8');
utf8HashJava=variables.javaBigInt.toString(16);
#utf8HashCF#
#utf8HashJava#
我认为这不是CF哈希,因为如果将CF与Java进行比较,它们会创建相同的哈希。我的框上的CF和Java输出“65a8e27d8879283831b664bd8b7f0ad4”和我将强制转换更改为varchar时的SQL哈希匹配(32)

在过去,当我需要进行任何类型的散列创建和比较时,我创建了一个返回字符串的服务,这样您就不必担心跨平台的算法问题。您也可以让sql为您完成这一切,但是您的业务逻辑在错误的层中,但每个层都有自己的逻辑

<cfscript>
    helloWorld = "Hello, World!";
    utf8HashCF = lcase(hash(helloWorld, 'MD5', 'UTF-16LE'));
</cfscript>
<cfoutput>
    #utf8HashCF# <br />
</cfoutput>

helloWorld=“你好,世界!”;
javaString=CreateObject(“java”,“java.lang.String”).Init(helloWorld);
javaHash=CreateObject(“java”、“java.security.MessageDigest”).getInstance(“MD5”);
javaHash.reset();
update(javaString.getBytes(“UTF-8”)、0、javaString.length();
javaBigInt=CreateObject(“java”,“java.math.biginger”).Init(1,javaHash.digest());
utf8HashCF=lcase(hash(helloWorld,'MD5','UTF-8');
utf8HashJava=variables.javaBigInt.toString(16);
#utf8HashCF#
#utf8HashJava#
默认情况下,SQL Server对nvarchar字段使用UTF-16小端字节顺序字符集。 在ColdFusion中,必须使用“UTF-16LE”字符集


helloWorld=“你好,世界!”;
utf8HashCF=lcase(hash(helloWorld,'MD5','UTF-16LE');
#utf8HashCF#

默认情况下,SQL Server对nvarchar字段使用UTF-16小端字节顺序字符集。 在ColdFusion中,必须使用“UTF-16LE”字符集


helloWorld=“你好,世界!”;
utf8HashCF=lcase(hash(helloWorld,'MD5','UTF-16LE');
#utf8HashCF#

看起来是其他人在.Net中遇到了这个问题,我没有办法测试它,但可能CF UTF-16编码默认为Big-Endian?如果要将普通字符串值与SQL hased列进行比较,请将普通字符串传递给SQL并使用SQL进行哈希。然后与该列进行比较。您是否有任何特定要求来检查CF代码中是否存在此问题?看起来其他人对.Net有此问题,我没有办法测试它,但CF UTF-16编码默认为Big-Endian?如果您想将纯字符串值与SQL hased列进行比较,请将纯字符串传递给使用SQL的SQL&hash。然后与该列进行比较。您对在CF代码中检查这一点有什么具体要求吗?正如Adam发布的一样-我检查了SQL Server 2008,但将查询更改为CAST(“Hello world!”作为varchar(32))并获得了CF UTF-8哈希。正如Adam发布的一样-我检查了SQL Server 2008,但将查询更改为CAST(“Hello world!”作为varchar(32))并获得了CF UTF-8哈希。这是正确的。我想我已经用哈希函数尝试了这种编码,但显然没有。我很想看到一些关于nvarchar endianess的文档。奇怪的是,当我尝试使用@StefanoDiFabio java版本使用UTF-16LE时,它没有起作用。ColdFusion是在引擎盖下多做一两步来让它工作。这是正确的。我想我已经用哈希函数尝试了这种编码,但显然没有。我很想看看
<cfscript>
    helloWorld = "Hello, World!";
    utf8HashCF = lcase(hash(helloWorld, 'MD5', 'UTF-16LE'));
</cfscript>
<cfoutput>
    #utf8HashCF# <br />
</cfoutput>