una number hexadecimal entero convertir cadena binario base_convert php encoding character-encoding numeric alphanumeric

php - number - convertir una base numérica 10 en una base 62(a-zA-Z0-9)



php binary to string (9)

Tengo un número en la base 10. ¿Hay alguna forma de traducirlo a una base 62?

Ejemplo:

echo convert(12324324); // returns Yg3 (fantasy example here)

PHP base_convert() puede convertir hasta la base 36.


Apenas fue probado y funciona en un producto realmente grande. Solo copia estas funciones y usa. Si es necesario, puede organizar $ baseChars secuencialmente, lo necesito para mezclar.

/** * decToAny converter * * @param integer $num * @param string $baseChars * @param integer $base * @return string */ function decToAny($num, $baseChars = '''', $base = 62, $index = false) { $baseChars = empty($baseChars) ? ''HbUlYmGoAd0ScKq6Er5PuZp3OsQCh4RfNMtV8kJiLv9yXeI1aWgFj2zTx7DnBw'' : $baseChars; if (!$base) { $base = strlen($index); } else if (!$index) { $index = substr($baseChars, 0, $base); } $out = ""; for ($t = floor(log10($num) / log10($base)); $t >= 0; $t--) { $a = floor($num / pow($base, $t)); $out = $out . substr($index, $a, 1); $num = $num - ( $a * pow($base, $t) ); } return $out; }

Método inverso

/** * anyTodec converter * * @param string $num * @param string $baseChars * @param integer $base * @return string */ function anyToDec($num, $baseChars = '''', $base = 62, $index = false) { $baseChars = empty($baseChars) ? ''HbUlYmGoAd0ScKq6Er5PuZp3OsQCh4RfNMtV8kJiLv9yXeI1aWgFj2zTx7DnBw'' : $baseChars; if (!$base) { $base = strlen($index); } else if (!$index) { $index = substr($baseChars, 0, $base); } $out = 0; $len = strlen($num) - 1; for ($t = 0; $t <= $len; $t++) { $out = $out + strpos($index, substr($num, $t, 1)) * pow($base, $len - $t); } return $out; }


Esta función tiene la misma salida que GNU Precisión múltiple, si es posible ...

<?php function base_convert_alt($val,$from_base,$to_base){ static $gmp; static $bc; static $gmp62; if ($from_base<37) $val=strtoupper($val); if ($gmp===null) $gmp=function_exists(''gmp_init''); if ($gmp62===null) $gmp62=version_compare(PHP_VERSION,''5.3.2'')>=0; if ($gmp && ($gmp62 or ($from_base<37 && $to_base<37))) return gmp_strval(gmp_init($val,$from_base),$to_base); if ($bc===null) $bc=function_exists(''bcscale''); $range=''0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz''; if ($from_base==10) $base_10=$val; else { $n=strlen(($val="$val"))-++$ratio; if ($bc) for($i=$n;$i>-1;($ratio=bcmul($ratio,$from_base)) && $i--) $base_10=bcadd($base_10,bcmul(strpos($range,$val[$i]),$ratio)); else for($i=$n;$i>-1;($ratio*=$from_base) && $i--) $base_10+=strpos($range,$val[$i])*$ratio; } if ($bc) do $result.=$range[bcmod($base_10,$to_base)]; while(($base_10=bcdiv($base_10,$to_base))>=1); else do $result.=$range[$base_10%$to_base]; while(($base_10/=$to_base)>=1); return strrev($to_base<37?strtolower($result):$result); } echo base_convert_alt(''2661500360'',7,51); // Output Hello


Para números grandes, es posible que desee utilizar la biblioteca de PHP BC

function intToAny( $num, $base = null, $index = null ) { if ( $num <= 0 ) return ''0''; if ( ! $index ) $index = ''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ''; if ( ! $base ) $base = strlen( $index ); else $index = substr( $index, 0, $base ); $res = ''''; while( $num > 0 ) { $char = bcmod( $num, $base ); $res .= substr( $index, $char, 1 ); $num = bcsub( $num, $char ); $num = bcdiv( $num, $base ); } return $res; }


Una implementación más simple (y posiblemente más rápida) que no usa pow ni log :

function base62($num) { $index = ''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ''; $res = ''''; do { $res = $index[$num % 62] . $res; $num = intval($num / 62); } while ($num); return $res; }


tener una serie de caracteres como:

$chars = array( 1 => ''a'', 2 => ''b'', //.... 27 => ''A'', 28 => ''B'' ); function getCharacter($key) { if(array_key_exists($key, $chars[$key])) return $chars[$key]; return false; } function getNumber($char) { return array_search($char, $chars); }


http://us3.php.net/manual/en/function.base-convert.php#52450

<?php // Decimal > Custom function dec2any( $num, $base=62, $index=false ) { if (! $base ) { $base = strlen( $index ); } else if (! $index ) { $index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ,0 ,$base ); } $out = ""; // this fix partially breaks when $num=0, but fixes the $num=238328 bug // also seems to break (adds a leading zero) at $num=226981 through $num=238327 *shrug* // for ( $t = floor( log10( $num ) / log10( $base - 1 ) ); $t >= 0; $t-- ) { // original code: for ( $t = floor( log10( $num ) / log10( $base ) ); $t >= 0; $t-- ) { $a = floor( $num / pow( $base, $t ) ); $out = $out . substr( $index, $a, 1 ); $num = $num - ( $a * pow( $base, $t ) ); } return $out; } ?>

Parámetros:

$num - tu entero decimal

$base - base a la que desea convertir $num (déjelo 0 si está proporcionando $index u omita si está usando el valor predeterminado (62))

$index : si desea usar la lista de dígitos predeterminada (0-1a-zA-Z), omita esta opción, de lo contrario, proporcione una cadena (ej .: "zyxwvu")

<?php // Custom > Decimal function any2dec( $num, $base=62, $index=false ) { if (! $base ) { $base = strlen( $index ); } else if (! $index ) { $index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $base ); } $out = 0; $len = strlen( $num ) - 1; for ( $t = 0; $t <= $len; $t++ ) { $out = $out + strpos( $index, substr( $num, $t, 1 ) ) * pow( $base, $len - $t ); } return $out; } ?>

Parámetros:

$num - su número personalizado (cadena) (ej .: "11011101")

$base - base con la que se codificó $num (déjelo 0 si está proporcionando $index u omita si está usando el valor predeterminado (62))

$index : si desea usar la lista de dígitos predeterminada (0-1a-zA-Z), omita esta opción, de lo contrario, proporcione una cadena (ej .: "abcdef")


ANTIGUO : Una solución rápida y sucia puede ser usar una función como esta:

function toChars($number) { $res = base_convert($number, 10,26); $res = strtr($res,''0123456789'',''qrstuvxwyz''); return $res; }

La conversión de base convierte su número a una base donde los dígitos son 0-9a-p y luego elimina los dígitos restantes con una rápida sustitución de caracteres.

Como puede observar, la función es fácilmente reversible.

function toNum($number) { $res = strtr($number,''qrstuvxwyz'',''0123456789''); $res = base_convert($number, 26,10); return $res; }

Por cierto, ¿para qué usarías esta función?

Editar:

Basado en el cambio de la pregunta y en la respuesta de @jnpcl, aquí hay un conjunto de funciones que realizan la conversión básica sin usar pow y log (toman la mitad del tiempo para completar las pruebas).

Las funciones funcionan solo para valores enteros.

function toBase($num, $b=62) { $base=''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ''; $r = $num % $b ; $res = $base[$r]; $q = floor($num/$b); while ($q) { $r = $q % $b; $q =floor($q/$b); $res = $base[$r].$res; } return $res; } function to10( $num, $b=62) { $base=''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ''; $limit = strlen($num); $res=strpos($base,$num[0]); for($i=1;$i<$limit;$i++) { $res = $b * $res + strpos($base,$num[$i]); } return $res; }

La prueba:

for ($i = 0; $i<1000000; $i++) { $x = toBase($i); $y = to10($x); if ($i-$y) echo "/n$i -> $x -> $y"; }


function convertBase10ToBase62($num){ $charset="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; $endChar=$charset[$num%62]; $rtn=""; if ( $num == "62" ) { $rtn=$rtn.$charset[1]; } else if ( $num >= 62 ) { $rtn=$rtn.$charset[intval($num/62)%62+1]; } $num=intval($num/62); while ($num > 61) { if ( is_int($num/62) == true ) { $rtn=$rtn.$charset[0]; } else { $rtn=$rtn.$charset[$num%62]; } $num=intval($num/62); } $rtn=$rtn.$endChar; echo "/n"; echo $rtn; return $rtn; }


function convertBase10ToBase62($num){ $charset="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; $rtn=""; $n=$num;$base=62; while($n>0){ $temp=$n%$base; $rtn=$charset[$temp].$rtn; $n=intval($n/$base); } return $rtn; }