Facebook LinkedIn SourceForge Twitter RSS LastFM
logologo

Convertir des nombres en base 62 avec PHP

Geoffray Warnants|09/02/2011|54 commentaires

Dans la continuité du billet très intéressant de Vincent Battaglia consacré à l'utilité du système de numération hexatridécimal (soit en base 36) dans l'algorithme d'un raccourcisseur d'URL, j'ai voulu savoir si utiliser d'autres systèmes de numération encore plus vastes, comme le base 62 évoqué à la fin de son article, pouvait se faire avec autant de facilité, ce qui permettrait de générer des URL encore plus courtes à moindre effort.

Comme il l'a déjà bien expliqué, le principal critère qui influencera le choix entre l'une de ces deux bases est certainement le souci de la sensibilité à la casse. En effet, la base 36 se concentre sur le système alphanumérique minuscule tandis que la base 62 inclut aussi les caractères majuscules.

D'autre part, il va évidemment de soi qu'au plus la base est élevée (autrement dit au plus l'éventail de symboles possibles est vaste), au plus un nombre peut-être représenté de manière concise. Dans le cadre des raccourcisseurs d'URL, c'est donc aussi un critère primordial. Non seulement pour l'économie de caractères que cela implique, mais aussi pour le nombre d'identifiants que le service pourra gérer, et donc le nombre d'URL qu'il pourra prétendre offrir. Bien que la plupart des services actuels comme TinyURL, bit.ly ou goo.gl semblent s'être limités à une base 62, d'autres sont plus aventureux, comme par exemple le service (belge, disons-le !) http://ui.tl qui affirme être le plus concis du marché par l'utilisation d'une base 163, prenant ainsi le risque d'inclure des caractères accentués dans ses résultats.

Lors de la mise en pratique, je fus tout d'abord surpris de découvrir que la fonction base_convert de PHP ne supporte pas la conversion d'un nombre en base 62. L'occasion étant trop tentante, j'en ai profité pour réécrire une fonction sensiblement identique permettant cette fois de jongler entre différentes bases arbitraires avec une totale liberté.
Par la même occasion, j'y ai ajouté au travers d'un dernier paramètre optionnel la possibilité de spécifier le jeu de caractères à prendre en compte lors de la conversion. J'y vois plusieurs cas d'utilisation concrets, comme par exemple :

  • Pouvoir déjouer le caractère prédictif inhérent à ce genre de conversion, en spécifiant un alphabet dont l'ordre aura été préalablement altéré.
  • Pouvoir générer des valeurs "user-friendly", en omettant par exemple les caractères susceptibles de prêter à confusion lors de la lecture, tels o,O,0,1,l, etc...
  • Pouvoir définir son propre jeu de caractères, qui pourrait par exemple inclure des caractères spéciaux.
/**
 * Convertit un nombre entre différentes bases.
 *
 * @param   string      $number     Le nombre à convertir
 * @param   int         $frombase   La base du nombre
 * @param   int         $tobase     La base dans laquelle on doit le convertir
 * @param   string      $map        Eventuellement, l'alphabet à utiliser
 * @return  string|false            Le nombre converti ou FALSE en cas d'erreur
 * @author  Geoffray Warnants
 */
function base_to($number, $frombase, $tobase, $map=false)
{
    if ($frombase<2 || ($tobase==0 && ($tobase=strlen($map))<2) || $tobase<2) {
        return false;
    }

    if (!$map) {
        $map = implode('',array_merge(range(0,9),range('a','z'),range('A','Z')));
    }

    // conversion en base 10 si nécessaire
    if ($frombase != 10) {
        $number = ($frombase <= 16) ? strtolower($number) : (string)$number;
        $map_base = substr($map,0,$frombase);
        $decimal = 0;
        for ($i=0, $n=strlen($number); $i<$n; $i++) {
            $decimal += strpos($map_base,$number[$i]) * pow($frombase,($n-$i-1));
        }
    } else {
        $decimal = $number;
    }

    // conversion en $tobase si nécessaire
    if ($tobase != 10) {
        $map_base = substr($map,0,$tobase);
        $tobase = strlen($map_base);
        $result = '';
        while ($decimal >= $tobase) {
            $result = $map_base[$decimal%$tobase].$result;
            $decimal /= $tobase;
        }
        return $map_base[$decimal].$result;
    }
    return $decimal;
}

Pour se faire une idée de l'allure que peuvent avoir les valeurs retournées par cette fonction, voici à titre indicatif les résultats d'une série de conversions entre différentes bases. En ce qui concerne la base 163, j'ai considéré le jeu de caractères revendiqué par le service http://ui.tl.

base 10 base 16 base 36 base 62 base 163
100 64 2s 1C Æ
1000 3e8 rs g8
10000 2710 7ps 2Bi e%
100000 186a0 255s q0U %}I
1000000 f4240 lfls 4c92 OIÌ
10000000 989680 5yc1s FXsk $6Ô@
100000000 5f5e100 1njchs 6LAze @gÉ1
1000000000 3b9aca00 gjdgxs 15FTGg #5Û#.
10000000000 2540be400 4ldqpdk aUKYOs 6^/5Ç

<<< Retour

Vos commentaires

37 commentaires postés

Gabrielle Durand
30/06/2020 13:50Posté par Gabrielle Durand
Je ne connais rien en termes de langage de programmation. Mais en regardant votre site, j?ai envie de le tester. Est-ce que quelqu?un peut m?aider pour apprendre les bases de ce truc?? Merci d?avance pour votre collaboration.
Carine Gaston
30/06/2020 09:45Posté par Carine Gaston
Les internautes cherchent des nouvelles choses intéressantes chaque jour. Et je pense que votre langage va aider pas mal de personnes avec ce genre de problèmes. Mais en ce qui me concerne, je ne trouve pas d?intérêt à cela.
Patricia Bernard
29/06/2020 07:11Posté par Patricia Bernard
Je trouve qu?il existe des personnes qui attendent trop les autres pour résoudre tous ses problèmes. Même si on leur donne de nombreuses solutions, ils cherchent toujours des problèmes à la solution qu?on lui propose.
Sabrina Georges
28/06/2020 20:43Posté par Sabrina Georges
Bien sûr, les internautes peuvent chercher toutes les choses qui leurs intéressent. Mais quand quelqu?un donne des solutions pour résoudre ton problème, il faut le remercier sans faire de la discussion, même si cela ne te va pas.
Diana Jerry
24/06/2020 22:08Posté par Diana Jerry
Ne vous souciez pas du fait qu?elles exagèrent, mais compatissez et donnez des solutions si vous en avez. Votre remarque a tendance à juger les gens, pourtant, on n?est pas là pour cela, je crois.
Déborah Stéphane
24/06/2020 15:53Posté par Déborah Stéphane
Je dirais plutôt qu?il ne faut pas exagérer dans tout ce qu?on raconte. Certaines personnes en rajoutent toujours un peu trop. Je ne sais pas vraiment dans quel but elles font cela, mais c?est ridicule.
Lisa Anne
22/06/2020 22:41Posté par Lisa Anne
Si tu as des solutions pour résoudre les problèmes d?autrui, il faut les lui donner. N?attends pas qu?il te supplie. Dans la vie, personne n?est parfait et on a toujours besoin des autres. Le fait est qu?on ne sait pas ce que demain nous réserve.
Nina Thomas
22/06/2020 21:06Posté par Nina Thomas
Je trouve que presque tous les internautes cherchent à résoudre leurs problèmes personnels sur des sites. Il n?y a pas de mal à tout ça, je crois. Mais, il ne faut pas abuser quand même dans ce qu?on partage.
Larissa Dubois
17/06/2020 06:25Posté par Larissa Dubois
Merci beaucoup pour le tuyau. En fait, lorsqu?on rencontre des problèmes, il faut revoir les bonnes vieilles méthodes. Je ne maîtrise pas encore très bien ce langage, mais votre article m?a quand même bien aidé.
Emma Durand
15/06/2020 18:15Posté par Emma Durand
Je vois que de nombreuses personnes ont trouvé une solution à leur problème sur ce site. Mais à ce que je vois, il n?y a plus aucune réaction. C?est tellement dommage, je trouve. En tout cas, merci beaucoup.
Stéphanie Dupond
12/06/2020 07:14Posté par Stéphanie Dupond
Je ne crois pas que c?est de la male chance. D?ailleurs cela ne suffit pas pour vous qualifier comme étant une personne qui n?a pas de chance. Vous trouverez certainement une solution à votre problème ailleurs.
Anna Richard
10/06/2020 21:06Posté par Anna Richard
Personnellement, je compte parmi ceux qui ont trouvé une solution sur ce site. Je trouve dommage qu?ils aient arrêté les activités en fait. J?ai encore certaines questions en suspens. Mais, je ne sais pas à qui m?adresser.
cialis online
10/06/2020 13:38Posté par cialis online
cialis online
Rose Mallard
08/06/2020 22:23Posté par Rose Mallard
En effet, je crois que vous avez raison. Le fait est que moi-même j?ai trouvé pas mal de trucs intéressants et qui m?ont beaucoup aidé sur ce site. Seulement, je trouve dommage qu?il ne réagisse plus actuellement.
Rachelle Gaston
08/06/2020 21:21Posté par Rachelle Gaston
Malgré le fait que ce site est un peu ancien. On peut trouver des trucs intéressants et de découvrir d?autre chose qu?on peut essayer. Merci beaucoup pour le partage de votre travail en tant que professionnel.
generic ventolin albuterol inhalers
08/06/2020 06:55Posté par generic ventolin albuterol inhalers
generic ventolin albuterol inhalers
clomid online no prescription
28/05/2020 19:21Posté par clomid online no prescription
clomid online no prescription
hydroxychloroquine 400 mg buy online
28/05/2020 16:43Posté par hydroxychloroquine 400 mg buy online
hydroxychloroquine 400 mg buy online
where can i buy cialis without a prescription
20/05/2020 18:47Posté par where can i buy cialis without a prescription
I'm not certain where you are acquiring your info, only swell
subject. I of necessity to expend some metre encyclopaedism a lot more than or understanding more than.
Thanks for excellent information I was looking for this data for
my deputation.
clomid order online
19/05/2020 05:10Posté par clomid order online
clomid order online
can i buy hydroxychloroquine over the counter
15/05/2020 17:03Posté par can i buy hydroxychloroquine over the counter
can i buy hydroxychloroquine over the counter
buy clomid online
14/05/2020 04:04Posté par buy clomid online
buy clomid online
cialis order online
28/04/2020 02:14Posté par cialis order online
cialis order online
buy cialis 20mg
25/04/2020 13:57Posté par buy cialis 20mg
buy cialis 20mg
cialis dosage
25/04/2020 13:28Posté par cialis dosage
cialis dosage
hydroxychloroquine virus
31/03/2020 07:29Posté par hydroxychloroquine virus
hydroxychloroquine virus
Amandine
20/03/2020 08:48Posté par Amandine
Bonjour,
Merci pour le partage, mais c?est vraiment utile pour moi.
Harlie
19/03/2020 08:58Posté par Harlie
Bonjour,
Merci pour cet article, c?est vraiment utile.
Rio
19/03/2020 08:57Posté par Rio
Bonjour,
Merci pour cet article, c?est vraiment utile.
Maxime
23/02/2020 01:14Posté par Maxime
Du moment que ces petites astuces donnent un résultat positif, je suis preneur. Un grand merci pour cet article.
Rossignol
30/09/2019 19:10Posté par Rossignol
Jusqu'à présent je n'ai pas eu à utiliser le base 62. Mais l'info est à mettre dans un coin de la tête.
Spectacleinthefarm
12/02/2019 09:53Posté par Spectacleinthefarm
Dommage que le blog n'est plus mis à jour.
Rachel
19/09/2017 12:57Posté par Rachel
Bonjour,j'aime le style de votre blog, beaucoup de articles sont utiles à lire!!!
Pierre
09/08/2017 10:56Posté par Pierre
Merci beaucoup pour ce petit code PHP que je recherchais.
nicod
15/10/2013 16:50Posté par nicod
Super!!!

j'ai juste une question, pourquoi lorsque que je fais un base_to de quelque chose en faisant l'inverse ça redonne pas pareil?
exemple:

echo base_to('musique', 32, 62); // qUOmj
echo base_to('qUOmj', 62, 32); // br9j0f
sacha
23/04/2013 14:35Posté par sacha
Merci pour cet article et ce code. Je vais voir pour l'intégrer sur mon site !
syndrael
09/02/2011 08:38Posté par syndrael
Même si la base 36 est utile, je trouve que jouer sur le case-sensitive dans l'URL n'est pas approprié, mais ce n'est que mon avis..
En effet, les noms de domaines sont case-insensitive, ou si je me trompe, ont toujours été définis en minuscule. Donc une partie case-insensitive suivie d'une autre case-sensitive, je trouve ça 'illogique'
S.

Réagir à cet article

*


(Ne sera pas publiée, servira uniquement à afficher votre gravatar)


(Lien en dur et dofollow)

zend framework