特定の言語で実装していたコードの一部を、別の言語に置き換えたいケースってありますよね。
オリジナルのメソッド(関数)ならともかく、言語の標準仕様となると中まで追いかけるのが大変です。
今回は Kotlin の Object の hashCode(ハッシュ値)を 16進数化したものと、
String.hashCode()
Integer.toHexString()
UUID の生成ロジックを PHP に置き換えてみましたので紹介します。
UUID.randomUUID().toString()
Kotlin
まずは Kotlin の実装から。
UUID が util パッケージにあるので便利ですね。
1 2 3 4 5 6 | import java.util.UUID val hc = "itneko".hashCode() println("hc : $hc") println("hex : ${Integer.toHexString(hc)}") println("uuid: ${UUID.randomUUID().toString()}") |
結果は以下の通り。
hc : -1178400506
hex : b9c30906
uuid: ad36245d-b310-4130-83c8-e24ec2b886ac
PHP
では、上記のコードを PHP で実現してみましょう。
hashcode
まず hashCode() については、今回は String ですし Object のものをそのまま利用するとしましょう。
PHP の hash 関数で特定のアルゴリズムを指定すればいいと思ったのですが、それほど甘くなかった・・・。
10 年くらい前の記事ですが、今もこの方法がスタンダードなのだろうか。
Kotlin(Java)の Object が持つ hashcode と似たようなロジックですが、オーバーフローの制御が入ってますね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function overflow32($v) { $v = $v % 4294967296; if ($v > 2147483647) { return $v - 4294967296; } else if ($v < -2147483648) { return $v + 4294967296; } else { return $v; } } function hashCode($s) { $h = 0; $len = strlen($s); for ($i = 0; $i < $len; $i++) { $h = overflow32(31 * $h + ord($s[$i])); } return $h; } |
overflow32 の関数の制御については以下の説明がありますね。
The java function, which is calculated using fixed hardware 32-bit signed values, involves 32-bit arithmetic overflow (intrinsic to the CPU) to keep the value as a 32-bit signed integer.
In PHP, you will need to manually perform that arithmetic overflow each time the $hash is updated:
固定ハードウェア 32 ビット符号付き値を使用して計算される Java 関数は、値を 32 ビット符号付き整数として保持するために (CPU に固有の) 32 ビット算術オーバーフローを伴います。
PHP では、$hash が更新されるたびに算術オーバーフローを手動で実行する必要があります。
hashCode 関数に通してから 16 進数に変換すれば、Kotlin の時と同じ値が取得できます。
dechex(hashCode(“itneko”));
UUID
UUID も標準関数が用意されていないとは・・・。
以下のサイトの「パターン2」がシンプルに書けて使いやすそうですね。
1 2 3 4 5 6 7 | preg_replace_callback( '/x|y/', function($m) { return dechex($m[0] === 'x' ? random_int(0, 15) : random_int(8, 11)); }, 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' ); |
まとめ
Kotlin で生成した文字列のハッシュ値と UUID を PHP で置き換えてみました。
PHP の標準関数で事足りないことがあるとは意外・・・。