2011-01-11 3 views
1

Instapaper (텍스트를 저장하는 북마크릿)가 북마크릿에 대한 URL을 생성하는 방법에 대해 궁금합니다.사용자 ID를 해시하는 것보다 더 짧은 GUID?

광산은 이러한 URL의 품질은 그들이 (그래서 다른 사람이 귀하의 계정에 저장할 수 없습니다) 충돌 결코해야하고, 정말 추측하지 않을 것입니다 www.instapaper.com/j/AnJHrfoDTRia

유사한의 스크립트 src에 있습니다.

나는 간단한 접근법이 자신의 전자 메일 주소 (고유성에 대한 가입시 확인 된 것으로 추정되는) 인 MD5 일 수 있지만 그 다음에는 긴 긴 문자열로 끝나야한다는 것을 알고 있습니다. 이것은 큰 문제는 아니지만, 너무 자주 충돌하지 않는 짧은 GUID에 대한 기술이 무엇인지 궁금합니다 (이것은 분명히 절충이지만 12 자 이상은 내 의견으로는 꽤 짧습니다)

답변

-2

MD5 사용자 이름 결과로 나오는 MD5 해시의 첫 번째 X 문자를 가져옵니다. 해당 값을 가진 URL 토큰이 이미 DB에 있는지 확인하십시오. 그렇다면 첫 번째 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을 생성하면됩니다.3262666762397899821056 개의 고유 조합과 md5에 대한 281474976710656 (** 1,100 만 배 ** 더 커졌습니다) – zerkms

2

당신은 기본 16 숫자로 MD5 해시를 처리하여 짧은 문자열을 얻을 수 있습니다 (즉, 문자를 사용 (0-9A-F) 예 기지 (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 (11 백만 시간 더 큰) 대 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); 
?> 

이것은 12 개의 문자로 된 가장 순수한 컬럼비아 사람의 72 비트를 제공합니다. 이 세트에는 대략 10^21 개의 숫자가 들어 있습니다. 즉, 충돌 가능성은 1 백만 명의 사용자가 발생한 후 10 억 분의 1 정도입니다.

이것은 암호화 awesomeness 생성을위한이 stackoverflow 대답의 약간의 수정입니다 : Secure random number generation in PHP.

관련 문제