开发者

Youtube URL-style hashes

I'm trying to find out how to build nice and short alpha numeric hashes like the kind used in youtube urls.

Exam开发者_StackOverflow社区ple: http://www.youtube.com/watch?v=rw71YOSXhpE

Where rw71YOSXhpE would convert into video number 12834233 (for example).

These integers could be reversed in PHP to an integer and then looked up in a database.

I've run the following in PHP:

<?
$algoList = hash_algos( );

foreach( $algoList as $algoName )
{
    echo $algoName . ": " . hash( $algoName, 357892345234 ) . "\n";
}
?>

But none of them come back with characters beyond the a-f you'd expect. Youtube have the whole english alphabet in upper and lower case. Any idea how they've done it?


You want to convert your integer to a different base, one which uses the full alphabet. Base64 could work but you will get strings which are longer than the original integer because the base64_encode() function takes a string, not an integer.

My suggestion would be to use the base_convert() function like so:

$id = 12834233;
$hash = base_convert($id, 10, 36);

and the reverse

$hash = '7n2yh'
$id = base_convert($hash, 36, 10);

This however will only use lowercase letters a-z and 0-9. If you wish to use all upper and lower case letters you would need to convert to base 62 (or higher if you use symbols). However to do this you will have to write your own code.

Edit: Gordon pointed out this great link to base62 encoding in php.


You could use base_convert() to convert your number into base 36, which uses 0-9 plus a-z, and which has the advantage that your URL parameter is not case-sensitive.


I had a similar problem, and wrote a class for myself just for this.

Documentation: http://www.hashids.org/php/

Souce: https://github.com/ivanakimov/hashids.php

You would use it like this:

require('lib/Hashids/Hashids.php');

$hashids = new Hashids\Hashids('salt value', 11);
$hash = $hashids->encrypt(12834233);

You would get the following $hash: Rz0zlKZGg6g

Provide your own unique string for the salt value. The 11 in the code is optional and stands for minimum hash length. (You can also define your own alphabet string as 3rd param to the constructor).

To decrypt the hash you would do this:

$numbers = $hashids->decrypt($hash);

So $numbers will be: [12834233]

(It's an array because hashids can encrypt/decrypt several numbers into one hash.)

EDIT:

  1. Changed urls to include both doc website and code source
  2. Changed example code to adjust to the main lib updates (current PHP lib version is 0.3.0 - thanks to all the open-source community for improving the lib)


probably a base64 encoding of a (part of) an md5 ? although I seems to recall that there are short ones and long ones, so it could be md5 or sha1. if you base64 decode the token you gave, with proper padding, the result is an 8 bit entity, so it's not a full md5. It could be only the first half of it.


Something similar could be done with base64_encode().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜