TwitterのツイートIDは、タイムスタンプ、マシンID、シークエンスを元に63bitでできているようで、このIDを分解し各値を取得、また逆に各値からツイートIDの生成をPHPで実装してみたいのですが、どうすれば分かりません。


具体的なPHPのソースがあると分かりやすくて有り難いです。
よろしくお願いします。

参考:
http://developer.smartnews.be/blog/2013/07/31/shakeflake-is-a-tool-for-generating-unique-id-numbers/

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:
  • 終了:2014/08/05 19:11:14
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.1

回答回数4964ベストアンサー獲得回数2150

ポイント100pt

やってみました。

http://developer.smartnews.be/blog/wp-content/uploads/sites/4/2013/07/bit_layout.png

http://developer.smartnews.be/blog/2013/07/31/shakeflake-is-a-tool-for-generating-unique-id-numbers/

サンプルに使ったのは、このツイートの ID。
https://twitter.com/a__kuma3/status/496321473632428032

<?php
/*
    https://twitter.com/a__kuma3/status/496321473632428032

     6e349c02a426000 : 496321473632428032 hex
    1FFFFFFFFFC00000 : timestamp mask
              3FF000 : machine id mask
                 FFF : sequence mask
 */

function parse_id($id) {
    $timestamp = ($id & 0x1FFFFFFFFFC00000) >> 22;
    $machine_id = ($id & 0x3FF000) >> 12;
    $sequence = ($id & 0xFFF);

    $padding = 1288834974657;
    $timestamp = $timestamp + $padding;

    return array($timestamp, $machine_id, $sequence);
}

function create_id($timestamp, $machine_id, $sequence) {
    $padding = 1288834974657;
    $timestamp = $timestamp - $padding;
    $id = ($timestamp << 22) | ($machine_id << 12) | ($sequence);
    return $id;
}



$id = 496321473632428032;
printf("id: %d (%x)\n", $id, $id);

// 分解してみる
$x = parse_id($id);
var_dump($x);

// 日時を確認
$d = new DateTime();
$d->setTimestamp($x[0] / 1000);
echo $d->format("Y-m-d H:i:s") . "\n";

// ID を再構成してみる
$id = create_id($x[0], $x[1], $x[2]);
printf("id: %d (%x)\n", $id, $id);

// 再構成した ID の日時を確認
$x = parse_id($id);
$d->setTimestamp($x[0] / 1000);
echo $d->format("Y-m-d H:i:s") . "\n";

?>

parse_id() が返す配列は、以下の値です。

  1. Unix 時刻(ミリ秒)
  2. 生成器のID
  3. 生成器ごとの通番

PhpFiddle で試してみたら、こんな感じの出力になりました。

id: 496321473632428032 (6e349c02a426000)
array(3) {
  [0]=>
  int(1407167235178)
  [1]=>
  int(38)
  [2]=>
  int(0)
}
2014-08-04 11:47:15
id: 496321473632428032 (6e349c02a426000)
2014-08-04 11:47:15

PhpFiddle は TimeZone が America/New_York だったので(var_dump すれば、分かります)、日本の時刻にすると +13時間ということで、8月5日の 0時47分になります。

参考元のサイトにあるように、時刻を Unix 時刻として扱うには、 1288834974657 (Thu Nov 04 10:42:54 JST 2010) のゲタを履かせる必要がありました。
2010年11月4日に何があったのか(*1)、Wikipedia の記載 を見ても、よく分からなかったのですが。

*1:twepoch という変数名なので、何かしらのエポックがあるような気はするのですが

id:wankodon

詳しい回答どうもありがとうございました。有り難く使わせて頂きます!
twepochは多分、ツイートIDが63bitに切り替わった日時で、一般には関係ない日時ではないかと思います。

2014/08/05 19:10:54

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません