Как создать совпадающий хэш MD5: SQL Server nvarchar Field против ColdFusion - PullRequest
1 голос
/ 10 апреля 2011

Я пытаюсь выяснить, как сгенерировать совпадающее хеш-значение MD 5 между SQL Server и ColdFusion. Основная причина заключается в том, что поле SQL Server имеет тип данных nvarchar, что, по-видимому, означает, что мне нужно что-то сделать с кодировкой строки, которую я бы хэшировал в ColdFusion или Java, чтобы она соответствовала, но я не могу понять это. Чтобы было ясно, если это поле SQL Server varchar, все работает.

Вот код, который я пытаюсь:

<code><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#

Производит

CF UTF-8:   86FB269D190D2C85F6E0468CECA42A20
CF UTF-16:  0C89A9720D83539E3723BB99C07D069F
SQL Server: f9a6119c6ec37ce652960382f8b59f2c

Итак, я думаю, мне нужно изменить последний аргумент, который я передаю, на hash(), чтобы он стал другой кодировкой, но я не могу понять это. Я также пометил этот вопрос как Java, потому что я более чем рад получить ответ и на этом языке.

Ответы [ 3 ]

3 голосов
/ 12 апреля 2011

По умолчанию SQL Server использует UTF-16 в наборе символов порядка байтов с прямым порядком байтов для полей nvarchar.В ColdFusion вы должны использовать набор символов «UTF-16LE».

<cfscript>
    helloWorld = "Hello, World!";
    utf8HashCF = lcase(hash(helloWorld, 'MD5', 'UTF-16LE'));
</cfscript>
<cfoutput>
    #utf8HashCF# <br />
</cfoutput>
1 голос
/ 10 апреля 2011

Мне любопытно, почему ваш столбец sql-сервера nvarchar; это не обязательно для хэшей. nvarchar предназначен для хранения расширенных наборов символов, которые вы не должны возвращать из хеш-функции.

Несмотря на это, я попробовал все алгоритмы хеширования, доступные в CF9, и ни один из них не сгенерировал хеш, который вы ищете.

Если вам не нужно оставить столбец nvarchar по какой-то причине, которую вы еще не объяснили, почему бы не изменить его на varchar?

0 голосов
/ 12 апреля 2011

Я не думаю, что это хеширование CF, потому что если вы сравните CF с Java, они создадут тот же хеш.Оба вывода CF и Java "65a8e27d8879283831b664bd8b7f0ad4" на моем боксе, и он соответствовал хешу SQL, когда я изменил приведение к varchar (32).

В прошлом, когда мне нужно было создавать хэши любого видаи для сравнения я создал сервис, который возвращает строку, чтобы вам не приходилось беспокоиться о проблемах кросс-платформенного алгоритма.Вы также можете просто сделать, чтобы sql сделал все это за вас, но тогда у вас есть бизнес-логика не в тех слоях, а в каждом из них.

<cfscript>
    helloWorld = "Hello, World!";

    javaString = CreateObject( "java", "java.lang.String" ).Init(helloWorld);
    javaHash = CreateObject( "java", "java.security.MessageDigest" ).getInstance("MD5");

    javaHash.reset();
    javaHash.update(javaString.getBytes("UTF-8"),0,javaString.length());

    javaBigInt = CreateObject( "java", "java.math.BigInteger" ).Init(1,javaHash.digest());

    utf8HashCF = lcase(hash(helloWorld, 'MD5', 'UTF-8'));
    utf8HashJava = variables.javaBigInt.toString(16);
</cfscript>
<cfoutput>
    #utf8HashCF# <br />
    #utf8HashJava#
</cfoutput>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...