web-dev-qa-db-fra.com

Comment créer un raccourcisseur d'URL?

Je souhaite créer un service de réduction d'URL dans lequel vous pouvez écrire une longue URL dans un champ de saisie et le service raccourcit l'URL en "http://www.example.org/abcdef".

Au lieu de "abcdef", il ne peut y avoir aucune autre chaîne de six caractères contenant a-z, A-Z and 0-9. Cela fait 56 à 57 milliards de chaînes possibles.

Mon approche:

J'ai une table de base de données avec trois colonnes:

  1. id, entier, auto-incrémenté
  2. long, chaîne, l'URL longue saisie par l'utilisateur
  3. short, string, l'URL raccourci (ou seulement les six caractères)

Je voudrais ensuite insérer la longue URL dans la table. Ensuite, je choisirais la valeur d'auto-incrémentation pour "id" et en créerais un hachage. Ce hachage doit alors être inséré sous la forme "short". Mais quelle sorte de hash devrais-je construire? Les algorithmes de hachage tels que MD5 créent des chaînes trop longues. Je n'utilise pas ces algorithmes, je pense. Un algorithme auto-construit fonctionnera également.

Mon idée:

Pour "http://www.google.de/", j'obtiens l'ID d'incrémentation automatique 239472. Ensuite, je fais les étapes suivantes:

short = '';
if divisible by 2, add "a"+the result to short
if divisible by 3, add "b"+the result to short
... until I have divisors for a-z and A-Z.

Cela pourrait être répété jusqu'à ce que le nombre ne soit plus divisible. Pensez-vous que c'est une bonne approche? As-tu une meilleure idée?

En raison de l'intérêt constant que suscite ce sujet, j'ai publié une solution efficace pour GitHub , avec des implémentations pour JavaScript , PHP , Python et Java . Ajoutez vos solutions si vous aimez:)

634
caw

Je voudrais continuer votre approche "convertir le nombre en chaîne". Cependant, vous réaliserez que votre algorithme proposé échoue si votre ID est un nombre premier et supérieur à 52 .

Contexte théorique

Vous avez besoin de Fonction Bijective f . Cela est nécessaire pour pouvoir trouver une fonction inverse g ('abc') = 123 pour votre f ( 123) = fonction 'abc' . Ça signifie:

  • Il ne doit y avoir aucun x1, x2 (avec x1 ≠ x2) qui fera f (x1) = f ( x2) ,
  • et pour chaque y , vous devez pouvoir trouver un x de sorte que f (x) = y .

Comment convertir l'ID en une URL raccourcie

  1. Pensez à un alphabet que nous voulons utiliser. Dans votre cas, c'est [a-zA-Z0-9]. Il contient 62 lettres .
  2. Prenons une clé numérique unique générée automatiquement (le id auto-incrémenté d'une table MySQL, par exemple).

    Pour cet exemple, je vais utiliser 125dix (125 avec une base de 10).

  3. Maintenant, vous devez convertir 125dix à X62 (base 62).

    125dix = 2 × 621 + 1 × 62 = [2,1]

    Cela nécessite l'utilisation de la division entière et du modulo. Un exemple de pseudo-code:

    digits = []
    
    while num > 0
      remainder = modulo(num, 62)
      digits.Push(remainder)
      num = divide(num, 62)
    
    digits = digits.reverse
    

    Mappez maintenant les indices 2 et 1 sur votre alphabet. Voici comment votre mapping (avec un tableau par exemple) pourrait ressembler à ceci:

    0  → a
    1  → b
    ...
    25 → z
    ...
    52 → 0
    61 → 9
    

    Avec 2 → c et 1 → b, vous recevrez cb62 comme l'URL raccourci.

    http://shor.ty/cb
    

Comment résoudre une URL raccourcie en ID initial

L'inverse est encore plus facile. Vous venez de faire une recherche inversée dans votre alphabet.

  1. e9a62 sera résolu en "4ème, 61ème et 0ème lettre de l'alphabet".

    e9a62 = [4,61,0] = 4 × 622 + 61 × 621 + 0 × 62 = 19158dix

  2. Recherchez maintenant votre enregistrement de base de données avec WHERE id = 19158 et faites la redirection.

Exemple d'implémentations (fournies par les commentateurs)

779
Marcel Jackwerth

Pourquoi voudriez-vous utiliser un hash?

Vous pouvez simplement utiliser une simple traduction de votre valeur d'auto-incrémentation en une valeur alphanumérique. Vous pouvez le faire facilement en utilisant une conversion de base. Supposons que l'espace de caractères (AZ, a-z, 0-9, etc.) comporte 40 caractères, convertisse l'id en un nombre en base 40 et utilise les caractères comme chiffres.

54
shoosh
public class UrlShortener {
    private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    private static final int    BASE     = ALPHABET.length();

    public static String encode(int num) {
        StringBuilder sb = new StringBuilder();
        while ( num > 0 ) {
            sb.append( ALPHABET.charAt( num % BASE ) );
            num /= BASE;
        }
        return sb.reverse().toString();   
    }

    public static int decode(String str) {
        int num = 0;
        for ( int i = 0; i < str.length(); i++ )
            num = num * BASE + ALPHABET.indexOf(str.charAt(i));
        return num;
    }   
}
48
richard

Ce n'est pas une réponse à votre question, mais je n'utiliserais pas d'URL abrégées sensibles à la casse. Ils sont difficiles à retenir, généralement illisibles (de nombreuses polices rendent 1 et l, 0 et O et d’autres caractères très similaires à ce qu’ils sont presque impossibles à faire la différence) et propices aux erreurs. Essayez d'utiliser uniquement des majuscules ou des minuscules.

Essayez également d’avoir un format dans lequel vous mélangez les chiffres et les caractères dans un format prédéfini. Certaines études montrent que les gens ont tendance à retenir un formulaire mieux que d'autres (pensez aux numéros de téléphone, où les numéros sont regroupés dans un formulaire spécifique). Essayez quelque chose comme num-char-char-num-char-char. Je sais que cela réduira les combinaisons, surtout si vous n’avez pas de majuscules et de minuscules, mais ce serait plus utilisable et donc utile.

32
Ash

Mon approche: Prenez l'ID de la base de données, puis Base36 l'encodez . Je ne voudrais PAS utiliser les lettres majuscules ET minuscules, car cela rend la transmission de ces URL par téléphone un cauchemar, mais vous pouvez bien sûr facilement étendre la fonction à un décodeur/base 62.

28
Michael Stum

Voici ma classe PHP 5.

<?php
class Bijective
{
    public $dictionary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    public function __construct()
    {
        $this->dictionary = str_split($this->dictionary);
    }

    public function encode($i)
    {
        if ($i == 0)
        return $this->dictionary[0];

        $result = '';
        $base = count($this->dictionary);

        while ($i > 0)
        {
            $result[] = $this->dictionary[($i % $base)];
            $i = floor($i / $base);
        }

        $result = array_reverse($result);

        return join("", $result);
    }

    public function decode($input)
    {
        $i = 0;
        $base = count($this->dictionary);

        $input = str_split($input);

        foreach($input as $char)
        {
            $pos = array_search($char, $this->dictionary);

            $i = $i * $base + $pos;
        }

        return $i;
    }
}
8
Xeoncross

Une solution Node.js et MongoDB

Puisque nous connaissons le format utilisé par MongoDB pour créer un nouvel ObjectId de 12 octets.

  • une valeur de 4 octets représentant les secondes depuis l'époque Unix,
  • un identifiant de machine à 3 octets,
  • un identifiant de processus à 2 octets
  • un compteur de 3 octets (dans votre machine), en commençant par une valeur aléatoire.

Exemple (je choisis une séquence aléatoire) a1b2c3d4e5f6g7h8i9j1k2l

  • a1b2c3d4 représente les secondes depuis l’époque Unix,
  • 4e5f6g7 représente l'identifiant de la machine,
  • h8i9 représente l'identifiant du processus
  • j1k2l3 représente le compteur, en commençant par une valeur aléatoire.

Comme le compteur sera unique si nous stockons les données dans la même machine, nous pouvons l’obtenir sans aucun doute sur le fait qu’elles seront dupliquées.

Ainsi, l'URL courte sera le compteur et voici un extrait de code supposant que votre serveur fonctionne correctement.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Create a schema
const shortUrl = new Schema({
    long_url: { type: String, required: true },
    short_url: { type: String, required: true, unique: true },
  });
const ShortUrl = mongoose.model('ShortUrl', shortUrl);

// The user can request to get a short URL by providing a long URL using a form

app.post('/shorten', function(req ,res){
    // Create a new shortUrl */
    // The submit form has an input with longURL as its name attribute.
    const longUrl = req.body["longURL"];
    const newUrl = ShortUrl({
        long_url : longUrl,
        short_url : "",
    });
    const shortUrl = newUrl._id.toString().slice(-6);
    newUrl.short_url = shortUrl;
    console.log(newUrl);
    newUrl.save(function(err){
        console.log("the new URL is added");
    })
});
6
Firas Omrane

Vous pouvez hacher l'URL entière, mais si vous voulez simplement raccourcir l'id, faites comme suggéré par marcel. J'ai écrit cette implémentation Python:

https://Gist.github.com/778542

4
bhelx

version C #:

public class UrlShortener 
{
    private static String ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    private static int    BASE     = 62;

    public static String encode(int num)
    {
        StringBuilder sb = new StringBuilder();

        while ( num > 0 )
        {
            sb.Append( ALPHABET[( num % BASE )] );
            num /= BASE;
        }

        StringBuilder builder = new StringBuilder();
        for (int i = sb.Length - 1; i >= 0; i--)
        {
            builder.Append(sb[i]);
        }
        return builder.ToString(); 
    }

    public static int decode(String str)
    {
        int num = 0;

        for ( int i = 0, len = str.Length; i < len; i++ )
        {
            num = num * BASE + ALPHABET.IndexOf( str[(i)] ); 
        }

        return num;
    }   
}
4
user1477388
// simple approach

$original_id = 56789;

$shortened_id = base_convert($original_id, 10, 36);

$un_shortened_id = base_convert($shortened_id, 36, 10);
3
phirschybar
alphabet = map(chr, range(97,123)+range(65,91)) + map(str,range(0,10))

def lookup(k, a=alphabet):
    if type(k) == int:
        return a[k]
    Elif type(k) == str:
        return a.index(k)


def encode(i, a=alphabet):
    '''Takes an integer and returns it in the given base with mappings for upper/lower case letters and numbers 0-9.'''
    try:
        i = int(i)
    except Exception:
        raise TypeError("Input must be an integer.")

    def incode(i=i, p=1, a=a):
        # Here to protect p.                                                                                                                                                                                                                
        if i <= 61:
            return lookup(i)

        else:
            pval = pow(62,p)
            nval = i/pval
            remainder = i % pval
            if nval <= 61:
                return lookup(nval) + incode(i % pval)
            else:
                return incode(i, p+1)

    return incode()



def decode(s, a=alphabet):
    '''Takes a base 62 string in our alphabet and returns it in base10.'''
    try:
        s = str(s)
    except Exception:
        raise TypeError("Input must be a string.")

    return sum([lookup(i) * pow(62,p) for p,i in enumerate(list(reversed(s)))])a

Voici ma version pour quiconque en a besoin.

2
MrChrisRodriguez

Si vous ne voulez pas réinventer la roue ... http://lilurl.sourceforge.net/

2
Alister Bulman

Je continue à incrémenter une séquence entière par domaine dans la base de données et j'utilise Hashids pour coder l'entier dans un chemin d'URL.

static hashids = Hashids(salt = "my app rocks", minSize = 6)

J'ai exécuté un script pour voir combien de temps il fallait jusqu'à épuiser la longueur du caractère. Pour six caractères, il peut faire 164,916,224 liens, puis passe à sept caractères. Bitly utilise sept caractères. Moins de cinq personnages me semble bizarre.

Hashids peut décoder le chemin de l'URL en un entier, mais une solution plus simple consiste à utiliser l'intégralité du lien court sho.rt/ka8ds3 en tant que clé primaire.

Voici le concept complet:

function addDomain(domain) {
    table("domains").insert("domain", domain, "seq", 0)
}

function addURL(domain, longURL) {
    seq = table("domains").where("domain = ?", domain).increment("seq")
    shortURL = domain + "/" + hashids.encode(seq)
    table("links").insert("short", shortURL, "long", longURL)
    return shortURL
}

// GET /:hashcode
function handleRequest(req, res) {
    shortURL = req.Host + "/" + req.param("hashcode")
    longURL = table("links").where("short = ?", shortURL).get("long")
    res.redirect(301, longURL)
}
2
AJcodez

Avez-vous omis volontairement O, 0 et i?

Je viens de créer une classe PHP basée sur la solution de Ryan.

<?php

    $shorty = new App_Shorty();

    echo 'ID: ' . 1000;
    echo '<br/> Short link: ' . $shorty->encode(1000);
    echo '<br/> Decoded Short Link: ' . $shorty->decode($shorty->encode(1000));


    /**
     * A Nice shorting class based on Ryan Charmley's suggestion see the link on Stack Overflow below.
     * @author Svetoslav Marinov (Slavi) | http://WebWeb.ca
     * @see http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener/10386945#10386945
     */
    class App_Shorty {
        /**
         * Explicitly omitted: i, o, 1, 0 because they are confusing. Also use only lowercase ... as
         * dictating this over the phone might be tough.
         * @var string
         */
        private $dictionary = "abcdfghjklmnpqrstvwxyz23456789";
        private $dictionary_array = array();

        public function __construct() {
            $this->dictionary_array = str_split($this->dictionary);
        }

        /**
         * Gets ID and converts it into a string.
         * @param int $id
         */
        public function encode($id) {
            $str_id = '';
            $base = count($this->dictionary_array);

            while ($id > 0) {
                $rem = $id % $base;
                $id = ($id - $rem) / $base;
                $str_id .= $this->dictionary_array[$rem];
            }

            return $str_id;
        }

        /**
         * Converts /abc into an integer ID
         * @param string
         * @return int $id
         */
        public function decode($str_id) {
            $id = 0;
            $id_ar = str_split($str_id);
            $base = count($this->dictionary_array);

            for ($i = count($id_ar); $i > 0; $i--) {
                $id += array_search($id_ar[$i - 1], $this->dictionary_array) * pow($base, $i - 1);
            }
            return $id;
        }
    }
?>
1
Svetoslav Marinov

Voici une fonction d'encodage d'URL décent pour PHP ...

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

Je ne sais pas si quelqu'un trouvera cela utile - il s'agit davantage d'une méthode de "hack n slash", mais elle est simple et fonctionne bien si vous souhaitez uniquement des caractères spécifiques.

$dictionary = "abcdfghjklmnpqrstvwxyz23456789";
$dictionary = str_split($dictionary);

// Encode
$str_id = '';
$base = count($dictionary);

while($id > 0) {
    $rem = $id % $base;
    $id = ($id - $rem) / $base;
    $str_id .= $dictionary[$rem];
}


// Decode
$id_ar = str_split($str_id);
$id = 0;

for($i = count($id_ar); $i > 0; $i--) {
    $id += array_search($id_ar[$i-1], $dictionary) * pow($base, $i - 1);
} 
1
Ryan Charmley

Fonction basée sur la classe Xeoncross

function shortly($input){
$dictionary = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'];
if($input===0)
    return $dictionary[0];
$base = count($dictionary);
if(is_numeric($input)){
    $result = [];
    while($input > 0){
        $result[] = $dictionary[($input % $base)];
        $input = floor($input / $base);
    }
    return join("", array_reverse($result));
}
$i = 0;
$input = str_split($input);
foreach($input as $char){
    $pos = array_search($char, $dictionary);
    $i = $i * $base + $pos;
}
return $i;
}
0
Luis Neighbur
/**
 * <p>
 *     Integer to character and vice-versa
 * </p>
 *  
 */
public class TinyUrl {

    private final String characterMap = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    private final int charBase = characterMap.length();

    public String covertToCharacter(int num){
        StringBuilder sb = new StringBuilder();

        while (num > 0){
            sb.append(characterMap.charAt(num % charBase));
            num /= charBase;
        }

        return sb.reverse().toString();
    }

    public int covertToInteger(String str){
        int num = 0;
        for(int i = 0 ; i< str.length(); i++)
            num += characterMap.indexOf(str.charAt(i)) * Math.pow(charBase , (str.length() - (i + 1)));

        return num;
    }
}

class TinyUrlTest{

    public static void main(String[] args) {
        TinyUrl tinyUrl = new TinyUrl();
        int num = 122312215;
        String url = tinyUrl.covertToCharacter(num);
        System.out.println("Tiny url:  " + url);
        System.out.println("Id: " + tinyUrl.covertToInteger(url));
    }
}
0
Hrishikesh Mishra

Mise en œuvre dans Scala:

class Encoder(alphabet: String) extends (Long => String) {

  val Base = alphabet.size

  override def apply(number: Long) = {
    def encode(current: Long): List[Int] = {
      if (current == 0) Nil
      else (current % Base).toInt :: encode(current / Base)
    }
    encode(number).reverse
      .map(current => alphabet.charAt(current)).mkString
  }
}

class Decoder(alphabet: String) extends (String => Long) {

  val Base = alphabet.size

  override def apply(string: String) = {
    def decode(current: Long, encodedPart: String): Long = {
      if (encodedPart.size == 0) current
      else decode(current * Base + alphabet.indexOf(encodedPart.head),encodedPart.tail)
    }
    decode(0,string)
  }
}

Exemple de test avec Scala test:

import org.scalatest.{FlatSpec, Matchers}

class DecoderAndEncoderTest extends FlatSpec with Matchers {

  val Alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

  "A number with base 10" should "be correctly encoded into base 62 string" in {
    val encoder = new Encoder(Alphabet)
    encoder(127) should be ("cd")
    encoder(543513414) should be ("KWGPy")
  }

  "A base 62 string" should "be correctly decoded into a number with base 10" in {
    val decoder = new Decoder(Alphabet)
    decoder("cd") should be (127)
    decoder("KWGPy") should be (543513414)
  }

}
0
adrift

Ma version Python 3

base_list = list("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
base = len(base_list)

def encode(num: int):
    result = []
    if num == 0:
        result.append(base_list[0])

    while num > 0:
        result.append(base_list[num % base])
        num //= base

    print("".join(reversed(result)))

def decode(code: str):
    num = 0
    code_list = list(code)
    for index, code in enumerate(reversed(code_list)):
        num += base_list.index(code) * base ** index
    print(num)

if __== '__main__':
    encode(341413134141)
    decode("60FoItT")
0
wyx

Très bonne réponse, j'ai créé une implémentation Golang du bjf:

package bjf

import (
    "math"
    "strings"
    "strconv"
)

const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

func Encode(num string) string {
    n, _ := strconv.ParseUint(num, 10, 64)
    t := make([]byte, 0)

    /* Special case */
    if n == 0 {
        return string(alphabet[0])
    }

    /* Map */
    for n > 0 {
        r := n % uint64(len(alphabet))
        t = append(t, alphabet[r])
        n = n / uint64(len(alphabet))
    }

    /* Reverse */
    for i, j := 0, len(t) - 1; i < j; i, j = i + 1, j - 1 {
        t[i], t[j] = t[j], t[i]
    }

    return string(t)
}

func Decode(token string) int {
    r := int(0)
    p := float64(len(token)) - 1

    for i := 0; i < len(token); i++ {
        r += strings.Index(alphabet, string(token[i])) * int(math.Pow(float64(len(alphabet)), p))
        p--
    }

    return r
}

Hébergé sur github: https://github.com/xor-gate/go-bjf

0
Jerry Jacobs

Pourquoi ne pas simplement traduire votre identifiant en chaîne? Vous avez simplement besoin d’une fonction qui mappe un chiffre compris, par exemple, entre 0 et 61, sur une seule lettre (majuscule/minuscule) ou un chiffre. Appliquez-le ensuite pour créer des codes de 4 lettres, par exemple, et vous aurez couvert 14,7 millions d’URL.

0
cr333

J'ai une variante du problème, en ce sens que je stocke des pages Web de nombreux auteurs et que je dois empêcher la découverte de pages par devinettes. Ainsi, mes URL courtes ajoutent quelques chiffres supplémentaires à la chaîne Base-62 pour le numéro de page. Ces chiffres supplémentaires sont générés à partir des informations contenues dans l'enregistrement de page proprement dit et garantissent que seulement 1 URL sur 3844 sont valides (en supposant que le code Base-62 soit composé de 2 chiffres). Vous pouvez voir une description générale à la page http://mgscan.com/MBWL .

0
Graham

Voici une implémentation de Node.js qui est susceptible de bit.ly. générer une chaîne hautement aléatoire de sept caractères.

Il utilise le chiffrement Node.js pour générer un jeu de caractères hautement aléatoire, au lieu de sélectionner au hasard sept caractères.

var crypto = require("crypto");
exports.shortURL = new function () {
    this.getShortURL = function () {
        var sURL = '',
            _Rand = crypto.randomBytes(25).toString('hex'),
            _base = _Rand.length;
        for (var i = 0; i < 7; i++)
            sURL += _Rand.charAt(Math.floor(Math.random() * _Rand.length));
        return sURL;
    };
}
0
Hafiz Arslan

C'est ce que j'utilise:

# Generate a [0-9a-zA-Z] string
ALPHABET = map(str,range(0, 10)) + map(chr, range(97, 123) + range(65, 91))

def encode_id(id_number, alphabet=ALPHABET):
    """Convert an integer to a string."""
    if id_number == 0:
        return alphabet[0]

    alphabet_len = len(alphabet) # Cache

    result = ''
    while id_number > 0:
        id_number, mod = divmod(id_number, alphabet_len)
        result = alphabet[mod] + result

    return result

def decode_id(id_string, alphabet=ALPHABET):
    """Convert a string to an integer."""
    alphabet_len = len(alphabet) # Cache
    return sum([alphabet.index(char) * pow(alphabet_len, power) for power, char in enumerate(reversed(id_string))])

C'est très rapide et peut prendre de longs entiers.

0
Davide Muzzarelli

Pour une solution de qualité Node.js/JavaScript, reportez-vous au module id-shortener , qui a fait l’objet de tests approfondis et a été utilisé en production pendant des mois.

Il fournit un raccourcisseur id/URL efficace soutenu par un stockage enfichable par défaut à Redis , et vous pouvez même personnaliser votre jeu de caractères ID court et indiquer si le raccourcissement est correct ou non. idempotent . Il s'agit d'une distinction importante que tous les raccourcisseurs d'URL ne prennent pas en compte.

Par rapport aux autres réponses ici, ce module met en œuvre l'excellente réponse acceptée de Marcel Jackwerth ci-dessus.

Le cœur de la solution est fourni par le Redis Lua suivant extrait :

local sequence = redis.call('incr', KEYS[1])

local chars = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz'
local remaining = sequence
local slug = ''

while (remaining > 0) do
  local d = (remaining % 60)
  local character = string.sub(chars, d + 1, d + 1)

  slug = character .. slug
  remaining = (remaining - d) / 60
end

redis.call('hset', KEYS[2], slug, ARGV[1])

return slug
0
fisch2

Pour un projet similaire, pour obtenir une nouvelle clé, je crée une fonction d'encapsulation autour d'un générateur de chaîne aléatoire qui appelle le générateur jusqu'à obtenir une chaîne qui n'a pas déjà été utilisée dans ma table de hachage. Cette méthode ralentira une fois que votre espace de noms commencera à être saturé, mais comme vous l'avez dit, même avec seulement 6 caractères, vous disposez de beaucoup d'espace de noms.

0
Joel Berger