0

クライアントでは、ラッパーに入れた Rusha を使用しています。

function cSHA1(m){
  return (new Rusha).digest(m);
}

Nodeのネイティブcryptoモジュールを使用しているサーバーでは、

function sSHA1(m){
  var h = crypto.createHash('sha1');
  h.update(m);
  return h.digest('hex');
}

試してみよう:

cSHA1('foo')
"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"

sSHA1('foo')
'0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'

cSHA1('bar')
"62cdb7020ff920e5aa642c3d4066950dd1f01f4d"

sSHA1('bar')
'62cdb7020ff920e5aa642c3d4066950dd1f01f4d'

ここまでは順調ですね。

では、変化球を投げてみましょう...

cSHA1(String.fromCharCode(10047))
"5bab61eb53176449e25c2c82f172b82cb13ffb9d"

sSHA1(String.fromCharCode(10047))
'5bab61eb53176449e25c2c82f172b82cb13ffb9d'

いいよ。

私はひもを持っています。どうやってそれを手に入れたかは重要ではありません。とにかく長い話ですが、

s.split('').map(function(c){
    return c.charCodeAt();
})

両方の場所でまったく同じ結果が得られます。

[58, 34, 10047, 32, 79]

それでは、ハッシュしてみましょう。

s
":"✿ O"

cSHA1(s)
"a199372c8471f35d14955d6abfae4ab12cacf4fb"

s
':"? O'
sSHA1(s)
'fc67b1e4ceb3e57e5d9f601ef4ef10c347eb62e6'

これは私にかなりの悲しみを引き起こしました。なんてこったい?

4

1 に答える 1

0

PHP sha1 と Rusha の SHA1 ハッシュを比較すると、ドイツ語のウムラウト文字で同じ問題に遭遇しました。

理由は簡単です。Javascript の文字列は UTF16 であると判断した愚か者がいます。PHP はエンコーディングについて気にせず、そこにあるものだけを使用します。したがって、PHP に json_decode("\u00e4") を指定すると、これは 2 バイトの文字列 0xc3 0xa4 (UTF8) に変換されます。

代わりに、JS はこれ (0xE4) から単一の UTF16 バイトを作成します。Rusha のマニュアルでは、すべてのコードポイントが 256 未満でなければならないと明示的に述べています。

自分自身を助けるために、 http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txtのようなUTF18-to-8 ライブラリを使用してくださいsha.digest(utf16to8("\u00e4"))。これにより、rusha に正しいコードポイントが供給されます。

于 2014-01-24T19:40:03.363 に答える