Skip to content

Instantly share code, notes, and snippets.

@ozh
Last active December 21, 2015 12:38
Show Gist options
  • Select an option

  • Save ozh/6306765 to your computer and use it in GitHub Desktop.

Select an option

Save ozh/6306765 to your computer and use it in GitHub Desktop.
BaseXX encode / decode. Consider replacing YOURLS functions with this to drop bcmath dependency
<?php
class BaseEncDec {
public $alphabet;
public $base;
public function __construct( $alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ) {
$this->alphabet = $alphabet;
$this->base = strlen( $alphabet );
}
public function encode($num) {
$str = '';
while ($num > 0) {
$str = substr($this->alphabet, ($num % $this->base), 1) . $str;
$num = floor($num / $this->base);
}
return $str;
}
public function decode($str) {
$num = 0;
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$num = $num * $this->base + strpos($this->alphabet, $str[$i]);
}
return $num;
}
}
// Example:
// $base = new BaseEncDec( "omgOZH123" );
// $rand = mt_rand(0,PHP_INT_MAX);
// $enc = $base->encode( $rand );
// $dec = $base->decode( $enc );
@ozh
Copy link
Copy Markdown
Author

ozh commented May 2, 2015

For the record, these functions produce the exact same results (base_encode($val) == base_encode2($val)) but are 65% slower :

function base_encode2($num, $alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ) {
    $base_count = strlen($alphabet);
    $encoded = '';
    while ($num >= $base_count) {
        $div = $num/$base_count;
        $mod = ($num-($base_count*intval($div)));
        $encoded = $alphabet[$mod] . $encoded;
        $num = intval($div);
    }

    if ($num)
        $encoded = $alphabet[$num] . $encoded;

    return $encoded;
}

function base_decode2($num, $alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ) {
    $decoded = 0;
    $multi = 1;
    while (strlen($num) > 0) {
        $digit = $num[strlen($num)-1];
        $decoded += $multi * strpos($alphabet, $digit);
        $multi = $multi * strlen($alphabet);
        $num = substr($num, 0, -1);
    }

    return $decoded;
}

@ozh
Copy link
Copy Markdown
Author

ozh commented May 2, 2015

For the record, these functions produce the exact same results (base_encode($val) == base_encode2($val)) but are 20% slower :

// From http://snipplr.com/view/22246/base62-encode--decode/
function base_encode($val, $chars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
    $base = strlen( $chars );
    $str = '';
    do {
        $i   = fmod($val, $base);
        $str = $chars[ intval( $i ) ] . $str;
        $val = ( $val - $i ) / $base;
    } while( $val > 0 );
    return $str;
}

function base_decode($str, $chars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
    $base = strlen( $chars );
    $len = strlen($str);
    $val = 0;
    $arr = array_flip( str_split( $chars ) );
    for( $i = 0; $i < $len; ++$i ) {
        $val += $arr[ $str[ $i ] ] * pow( $base, $len - $i -1 );
    }
    return $val;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment