Node.jsで特定の文字列から固有のidを作成する方法について

投稿者: Anonymous

現在、uuid-by-stringを使用しています。
uuid-by-stringを使用すると、基本的には被らないuuidが作成されるのですが

const getUUID = require('uuid-by-string');
console.log("おっぱい:"+getUUID("おっぱい"));
console.log("ちっぱい:"+getUUID("ちっぱい"));

とすると、何故かuuidが被って、どちらも同じidで

おっぱい:A8BE6F3B-3DED-4879-8A0B-4705EEBAF673
ちっぱい:A8BE6F3B-3DED-4879-8A0B-4705EEBAF673

が生成されてしまうみたいです。
例が下品な単語ですみません…。
日本語には対応していないのでしょうか?
他に何か日本語文字列から、固有の英数字idを生成する方法はないでしょうか?

解決

他に何か日本語文字列から、固有の英数字idを生成する方法はないでしょうか?

大きく分けると、ハッシュ値を使う方法と、ASCII の範囲に収まる方式でエンコードする方法があります。
ハッシュ値を使う方法は、文字列が長くても得られる ID の長さを一定に出来ます。
しかし、元の文字列が長すぎなければ、エンコードしてそのまま ID に使えるかも知れません。

(UUID の例にはuuid モジュールを使用しています。uuid-by-string というモジュールより信頼できると思います)

"use strict"

// ハッシュ値の16進表記
const crypto = require("crypto")
function mkhash(str) {
    //const hash = crypto.createHash("md5")
    //const hash = crypto.createHash("sha1")
    const hash = crypto.createHash("sha256")
    hash.update(str)
    return hash.digest("hex")
}
console.log("hash:  ", mkhash("やかん"))

// UUID v5(sha1 のハッシュ値を用いて生成する方式)
// npm install uuid
const uuidv5 = require("uuid/v5")
const NAMESPACE_UUID = "78fab293-e73b-482b-b3cb-a1982e48e870" // 必要に応じて手元で生成
console.log("uuidv5:", uuidv5("やかん", NAMESPACE_UUID))

// 文字列の16進表記
console.log("hex:   ", new Buffer("やかん").toString("hex"))

// 文字列の Base64 (英数字の他に記号 +,/,= が混じります)
console.log("base64:", new Buffer("やかん").toString("base64"))

// 国際化ドメイン名の方式 (Punycode)
const punycode = require("punycode")
console.log("puny:  ", punycode.encode("やかん"))

// URI エンコード(パーセントエンコード)
console.log("uri:   ", encodeURIComponent("やかん"))

出力:

hash:   b640b4b18beb20bd80c031e1ef646c6fe2bdb336a292139814f01b8975d8c253
uuidv5: 582878e9-c602-5e5b-a493-4a9365a16010
hex:    e38284e3818be38293
base64: 44KE44GL44KT
puny:   u8j2fwb
uri:    %E3%82%84%E3%81%8B%E3%82%93
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *