1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

文字コードを指定してハッシュ値を算出する(Node.js)

Last updated at Posted at 2021-08-14

Node.jsでハッシュ値を算出する

これは、私が業務でとあるAPIのリクエストを作成していた時のことです。

そのAPIは、ある文字列からハッシュ値を算出して、
そのハッシュ値が一致するかどうかで認証を行っていたんです。

だから以下のようなコードからハッシュ値を算出して、リクエストを投げて、
レスポンスを取得できていました。

const crypto = require('crypto');

const data = 'abcdefg';
// ハッシュ値を算出(md5)
const hash = crypto.createHash('md5').update(data).digest('hex');

console.log(hash); // 7ac66c0f148de9519b8bd264312c4d64

ビルトインモジュールのcryptoを使うだけでハッシュ値を算出できるなんて、手軽でいいなあと思っていました。
何も問題は無かったんです。

ハッシュ値を算出する文字列に、マルチバイト文字が含まれるまでは...。

hash.update()

cryptoモジュールのhashクラスのupdateメソッドは、引数を2つ取ることができます。

update(data [, inputEncoding])

公式ドキュメントでは、
dataがstringであり、かつinputEncodingが省略された場合は、
utf8でのエンコードが適用される
(原文を意訳)、とあります。

そのAPIでは文字コードをWindows-31Jに指定して、
ハッシュ値を算出する必要がある仕様でした。

しかし、ハッシュ値算出の際に文字コードを指定しないと、
デフォルトのUTF-8で算出されるため、「ハッシュ値が一致しない」という事態が起きたのです。

では、update()の第2引数をWindows-31Jにすればいいかと言えば、サポート対象外なのでそうではなく...。1

特定の文字コードでハッシュ値を算出する

// UTF-8でハッシュ値が算出されるコード
const crypto = require('crypto');

const data = 'あいうえお';
// ハッシュ値を算出(md5)
const hash = crypto.createHash('md5').update(data).digest('hex');

console.log(hash); // 86deb27a32903da70a7b2348fcf36bc3

このままだと、UTF-8としてハッシュ値を算出されてしまいます。
今回はWindows-31Jという文字コードの文字列としてハッシュ値を算出したいので、
iconv-liteという文字コード変換パッケージを使います!

iconv-liteencode()を用いることで、
第一引数に指定した文字列を、第二引数に指定した文字コードへの変換ができます。

const iconv  = require('iconv-lite');
const data = iconv.encode('あいうえお', 'Windows-31j');

encode()の返り値はBufferになります。
先述のハッシュのupdate()は引数にBufferもとれるので、
encode()の返り値をそのまま渡すだけで、そこからハッシュ値を算出してくれます。

つまり、指定の文字コードでエンコードされたデータから、
ハッシュ値を算出することができる!

const crypto = require('crypto');
const iconv  = require('iconv-lite');

// Windows-31Jでハッシュ値を算出する
const data = iconv.encode('あいうえお', 'Windows-31j');
const hash = crypto.createHash('md5').update(data).digest('hex');

console.log(hash); // ad7cf5ce5313f8b3fc59d626b9aad653

ヨシ!
パッケージを使うことで、簡単にできました。
ありがたや...。

まとめ

  • ハッシュ値を算出するにはビルトインモジュールのcryptoを使う
  • 特定の文字コードでハッシュ値を算出を行うには、iconv-liteencode()でBufferにしたデータを渡すことで可能

これまでハッシュ値算出の時に、文字コードを意識したことはなかったので、
新たなことを知る良い経験になりました:smile:

  1. 文字エンコードサポート対象

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?