UNIXタイムスタンプからハッシュ生成

category-icon

 ppBlogバージョン1.7.7から採用している機能のひとつに、コメント通知のメールからダイレクトでログイン出来てコメント返信できるというのがあります。その際に、リンクのURLに付加する文字列が今いちランダムになっていないので、ちょっとアルゴリズムの見直しをしてみました。時限性を持たせるために、UNIXのタイムスタンプから生成したハッシュをリンクのURLに付加しているのですが、タイムスタンプをチェックしたいので、復元可能なものであることが必要です(一方向で良ければ、sha1関数Link を使えば良いけどニーズに合わない)。

 単純に、UNIXのタイムスタンプをppBlogで用意している暗号化関数my_encrypt()に通すと、タイムスタンプの性質上、最後数桁しか変化せず、それに対応して生成されたハッシュも下数桁しか変化しません。まぁ、これはmy_encrypt()の性能の問題なんですが、この部分はそんな高性能でなくてよいし、過去の資産との互換性も考えると my_encrypt()はいじりたくないです。

$unix_time1 = 1234560000; // 10桁のUNIXタイムスタンプ
$unix_time2 = 1234567890; // 上と下4桁が違うだけ
echo my_encrypt($unix_time1); // 結果は、VwoLV1MOAwhVBg
echo my_encrypt($unix_time2); // 結果は、VwoLV1MOBABcBg

こんな感じでえらく似通った文字列になる(--) なので、このタイムスタンプを逆順にして更に基数変換すればよいかなと。逆順にすれば、大きく数値が変動します。そこで、文字列を逆順にする関数はないかstr_reverseという関数名で探してみましたがなさそうです。なので、

$unix_time_reverse = join("", array_reverse(preg_split("//", time())));

という力技で暫くローカルのテスト環境で動かしていたんですが、いやきっとあるはずだと、もう一度マニュアルを探してみたらありました。

$unix_time_reverse = strrev(time());

strrevLink という名前でしたか・・・。

 実は、単に逆順にしただけでは、my_encrypt()のアルゴリズムからしてそう大きな変化は望めないので、更に base_convert()Link 関数を利用して10進数から2進数に変換します。decbinLink でも行けるかなと思ったんですが、扱える最大の数が10 進数の4294967295とのことで、これは使えない。

$unix_time_binary = base_convert(strrev(time()), 10, 2); // 10進数を2進数に変換

 これで最初に挙げた例だと、

$encoded1 = my_encrypt(base_convert(strrev("1234560000"), 10, 2));
 // 結果は、VwgIUlcJAglUBgEJU1RUUgdRVAk
$encoded2 =  my_encrypt(base_convert(strrev("1234567890"), 10, 2));
 // 結果は、VwkJU1cIAglVBwEJU1VVUgZRVQgJVgIEVFcGAwhT
$encoded3 =  my_encrypt(base_convert(strrev("1235064688"), 10, 2)); // 別の例
 // 結果は、VwgIU1YJAwhVBgAJUlRUUgZQVAgIVgMFVVYHAwhSUAdWCQ

まぁ、最初に比べるとだいぶマシかなと思います。さて、この復元ですが、逆の操作をするだけです。

$decoded = strrev(sprintf("%010s", base_convert(my_decrypt($encoded1), 2, 10)));
 // この場合は、1234560000 を返す

これで、元の10桁のタイムスタンプを取得できます。ひとつ注意する点は、順序を逆にした文字列を戻す際に、元のタイムスタンプによっては逆順にした文字列の先頭がゼロになる場合があるということです(上の例だと反転した0000654321654321と解釈される)。なので、sprintfLink 関数を用いて、ゼロで10桁になるように埋め合わせをしておきます。

sprintf("%010s", "654321"); // この結果は、0000654321

 実際の実装(?)としては、これらとsha1関数を組み合わせたりして、長い文字列を生成してます。

— posted by martin at 02:52 am   commentComment [0]  pingTrackBack [0]

この記事に対する TrackBack URL:

設定によりTB元のページに、こちらの記事への言及(この記事へのリンク)がなければ、TB受付不可となりますのであらかじめご了承下さい。

コメントをどうぞ。 名前(ペンネーム)と画像認証のひらがな4文字は必須で、ウェブサイトURLはオプションです。

ウェブサイト (U):

タグは使えません。http://・・・ は自動的にリンク表示となります

:) :D 8-) ;-) :P :E :o :( (TT) ):T (--) (++!) ?;w) (-o-) (**!) ;v) f(--; :B l_P~

     
T: Y: ALL: Online:
Created in 0.0064 sec.
prev
2021.12
next
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31