2011-01-11 12 views
1

Instapaper(テキストを保存するブックマークレット)がブックマークレットのURLをどのように生成するのだろうかと思います。ユーザーIDをハッシュするよりも短いGUID?

鉱山がwww.instapaper.com/j/AnJHrfoDTRia

に似た何かのスクリプトsrcを持ち、これらのURLの品質は、彼らが(ので、他の人があなたのアカウントに保存することはできません)衝突することはありませんする必要があり、実際には推測できないということです。

私は簡単なアプローチがMD5のメールアドレス(一意性のためにサインアップされたと思われる)と思われるかもしれませんが、その後はスーパーの長い文字列で終わるでしょう。これは大きな問題ではありませんが、あまりにも頻繁に衝突しない短いGUIDのテクニックについては疑問に思っています(これは明らかにトレードオフですが、上記の12文字は私の意見ではかなり短いです)

答えて

-2

MD5ユーザー名。結果のMD5ハッシュの最初のX文字を取得します。 DBにその値を持つURLトークンがすでに存在するかどうかを確認します。もしそうなら、最初のX + 1文字をとり、それを試してください。そうでない場合は、そのユーザーのトークンがあります。 DBにトークンを格納して、そこから探します。毎回、またはそれ以外のときにユーザー名からトークンを再作成しないでください。

おそらくX = 7で始まり、大部分のトークン世代に対して1-2回の試行が必要です。

また、指定されたユーザーのトークンを予測するのを困難にするために、ハッシュ計算に何か他のもの(たとえば、その番号または乱数)を追加することもできます。

+1

いつも '+1 char'となる(**予測可能**を意味する)場合、' name'の 'md5'を使う理由はありますか?なぜ 'md5(マイクロタイム(1))'または 'md5(uniqid())'だけではないのですか? – zerkms

+0

@zerkms:完全に受け入れられるオプション。あなたは 'md5(rand())'でも可能です。 – Amber

+0

また、容量を増やすには、md5を使用しないで、0-9a-zA-Zからランダムにcharを生成することをお勧めします。それは私たちに3226266762397899821056のユニークな組み合わせとmd5の281474976710656を与えます(** 1100万倍**大きい) – zerkms

2

リンクを(つまり、文字(0-9A-Fを使用して)ベース16番号としてMD5ハッシュを処理し、例えばベース36

<?php 
function gmp_convert($num, $base_a, $base_b) { 
    return gmp_strval (gmp_init($num, $base_a), $base_b); 
} 

$hash = md5("hello"); 
$hash2 = gmp_convert($hash,16,36); 
echo "$hash <br>"; //5d41402abc4b2a76b9719d911017c592 
echo $hash2; //5ir3t0ozoelrnauhrwyu1xfgy 

に変換することにより、より短い文字列を取得することができあなたが言及するすべての文字(大文字と小文字)を使用しているようだ。

these Q&As

0
<?php 

$length = 12; 

$chars = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z')); 

$hash = ''; 

for ($i = 0; $i < $length; $i++) { 
    $hash .= $chars[array_rand($chars)]; 
} 

var_dump($hash); 

から抽出された情報。これは、私たちのユニークな3226266762397899821056を与えますmd5(これはの110000000000000000)の281474976710656との組み合わせです。

ちょうど4つの文字(!!!)の場合、14776336のユニークな組み合わせで十分です。

0

Base64は、乱数の強力なセットを暗号化します。

<?php 
// get 72 pseudorandom bits in a base64 string of 12 characters 

$pr_bits = ''; 

// Unix/Linux platform? 
$fp = @fopen('/dev/urandom','rb'); 
if ($fp !== FALSE) { 
    $pr_bits .= @fread($fp,9); 
    @fclose($fp); 
} 

// MS-Windows platform? 
if (@class_exists('COM')) { 
    // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx 
    try { 
     $CAPI_Util = new COM('CAPICOM.Utilities.1'); 
     $pr_bits .= $CAPI_Util->GetRandom(9,0); 

     // if we ask for binary data PHP munges it, so we 
     // request base64 return value. We squeeze out the 
     // redundancy and useless ==CRLF by hashing... 
     if ($pr_bits) { $pr_bits = substr(md5($pr_bits,TRUE), 0, 9); } 
    } catch (Exception $ex) { 
     // echo 'Exception: ' . $ex->getMessage(); 
    } 
} 

$uid = base64_encode($pr_bits); 
?> 

これにより、純正コロンビア語の72ビットが12文字で表示されます。このセットにはおよそ10^21の数字が含まれています。これは、100万人のユーザーの後で、衝突の可能性が10億分の1になることを意味します。

これは、暗号のawesomenessを生成するためのこのstackoverflow答えの非常にわずかな変更です:Secure random number generation in PHP

関連する問題