Cómo generar a corto uid como «aX4j9Z» (en JS)

De mi aplicación web (en JavaScript) quiero generar a corto guid (para los diferentes objetos que son realmente diferentes tipos de cadenas y matrices de cadenas)

Quiero algo como «aX4j9Z» para mi uidos (guid).

Por lo que estos líquidos deben ser suficientemente ligeras como para la transferencia web y js de la cadena de procesamiento y muy singular por que no una gran estructura (no más de 10k de los elementos). Diciendo: «bastante único», me refiero a que después de la generación de la uid pude comprobar si este líquido hace ya existen en la estructura y regenerar que si lo hace.

  • ¿Qué es un «uid» y un «guid»? La forma más sencilla de generar valores únicos es comenzar con una cadena como «x», a continuación, se anexa un número generado por un contador, por lo que se obtiene «x0», «x1», y así sucesivamente. ¿Cuál es el contexto de «único»? Elemento de id y los nombres? Propiedades de algún objeto? Otros?
InformationsquelleAutor WHITECOLOR | 2011-06-06

7 Kommentare

  1. 107

    Ver @Mohamed respuesta para un pre-empaquetado de la solución (el shortid paquete). Prefiero que en lugar de otras soluciones en esta página si no tiene requisitos especiales.


    De 6 caracteres alfanuméricos de la secuencia es bastante bonito, de forma aleatoria índice de 10k de la colección (366 = 2.2 mil millones de dólares y 363 = 46656).

    function generateUID() {
        //I generate the UID from two parts here 
        //to ensure the random number provide enough bits.
        var firstPart = (Math.random() * 46656) | 0;
        var secondPart = (Math.random() * 46656) | 0;
        firstPart = ("000" + firstPart.toString(36)).slice(-3);
        secondPart = ("000" + secondPart.toString(36)).slice(-3);
        return firstPart + secondPart;
    }

    Líquidos generados aleatoriamente tendrá colisión después de la generación de ~ √N números (la paradoja de cumpleaños), por lo tanto, 6 dígitos son necesarios para la seguridad de la generación sin comprobar (la versión anterior sólo genera 4 dígitos que hubiera una colisión después de 1300 Id si usted no marca).

    Si usted hace una comprobación de colisiones, el número de dígitos puede ser reducido a 3 o 4, pero tenga en cuenta que el rendimiento se reducirá linealmente a la hora de generar más y más de Uidos.

    var _generatedUIDs = {};
    function generateUIDWithCollisionChecking() {
        while (true) {
            var uid = ("0000" + ((Math.random() * Math.pow(36, 4)) | 0).toString(36)).slice(-4);
            if (!_generatedUIDs.hasOwnProperty(uid)) {
                _generatedUIDs[uid] = true;
                return uid;
            }
        }
    }

    Considerar el uso secuencial del generador (por ejemplo,user134_item1, user134_item2, …) si necesita singularidad y no imprevisibilidad. Usted podría «Hash» el secuencialmente cadena generada para recuperar la imprevisibilidad.

    Líquidos generados utilizando Math.random no es seguro (y usted no debe confiar en el cliente de todos modos). Hacer no confiar en su singularidad o la imprevisibilidad en tareas de misión crítica.

    • De niza. Eso es muy limpio. Podría usted explicar por qué + "1000" al final?
    • en la oportunidad que se genera un número aleatorio de «0», o «.000000000001», etc. y el final de la cadena termina como «4z». El «0000» se asegura de que siempre es de al menos 4 caracteres de largo
    • 0 es buggy en safari. Uso << 0 o |0
    • Hecho.
    • Por cada 10.000 números, hay al menos un 1:160 probabilidad de que dos identificadores será el mismo. El substr podría ser más largo, pero ¿por qué el uso de números aleatorios en todos?
    • Porque el OP quiere un «corto» UID.
    • así que ¿por qué utilizar un número aleatorio en todo? Utilizando un contador y valores 0-9,a-z, A-Z ofrece 62^3 combinaciones posibles (238,328)) con la singularidad garantizado y sólo 3 caracteres.
    • Un simple contador que va «n1» –> «n10000» y en funcionaría así. Yo iba en el supuesto de que el OP tenía una razón para no hacerlo
    • Que funciona bien si debe ser única para el cliente en una sesión asegurándose de que no hay condición de carrera.
    • ¿cómo puede haber una condición de carrera en la llanura de javascript? Ver mi respuesta, ¿ves alguna posibilidad de que? La única posibilidad que yo veo es que si se utiliza con un XHR de devolución de llamada, a continuación, los Identificadores no pueden ser squential con las llamadas XHR (dado que puede devolver fuera de secuencia). Que puede ser fijado por obtener el ID antes de hacer la llamada. Oh, y la singularidad puede sólo ser garantizado por el cliente, de lo contrario se tiene que hacer en el servidor.
    • Bien, Gracias, creo que es muy buen método. Voy a estar tratando de utilizar.
    • esto no funciona. He probado el código y hay una pequeña posibilidad de tener el mismo uuid, si haces algo como generar 10,000 a la vez. Este no es un verdadero UUID del generador. De matemáticas.aleatorio() funciona, pero no es pequeña.
    • Sí, hay un 2% de probabilidad de colisión entre 10000 IDs. La generación de 7 dígitos, se reduce a 0,06%. Pero siempre hay una pequeña posibilidad de colisión mientras los Identificadores son generados al azar con ninguna correlación.
    • Para los pequeños bloques de azar, el IDENTIFICADOR de esto funciona ++, corto y dulce, sin la necesidad de descargar un externo lib. Utilizando actualmente para generar Identificadores para la creación dinámica de los elementos HTML.

  2. 16

    También hay un impresionante mecanismo nacional de prevención de este paquete : shortid

    Increíblemente corto no secuencial url amigable único de identificación de generador.

    ShortId crea increíblemente corto no secuencial url amigable identificadores únicos. Perfecto para los acortadores de url, MongoDB y Redis ids, y cualquier otra identificación de los usuarios podrían ver.

    • Por defecto 7-14 url amigable caracteres: a-Z, a-z, 0-9, _-
    • No-secuencial, de modo que no son predecibles.
    • Apoya clúster (automáticamente), personalizada semillas, personalizada alfabeto.
    • Puede generar cualquier número de id sin duplicados, incluso millones por día.
    • Perfecto para juegos, especialmente si usted está preocupado acerca de hacer trampa, de modo que usted no quiere una manera fácil de adivinar id.
    • De aplicaciones puede ser reiniciado cualquier número de veces sin ningún tipo de posibilidad de la repetición de un id.
    • Popular reemplazo para Mongo ID/Mangosta ID.
    • Obras en el Nodo, io.js y navegadores web.
    • Incluye Mocha pruebas.

    Uso

    var shortid = require('shortid');
    console.log(shortid.generate()); //PPBqWA9
    • Esto debe ser aceptado respuesta en mi opinión. Otra opción, que es ni de cerca tan bueno, es, por supuesto, la sustitución de los guiones con los espacios, replace(/[-]/g, ''), que llega a una longitud de 32.
    • Muy de acuerdo con que la «descargar potencialmente dañinos paquete» debe ser la respuesta a preguntas de programación.
  3. 5

    El siguiente genera un 62^3 (238,328) valores únicos de 3 caracteres de caso, la sensibilidad es único y los dígitos están permitidos en todas las posiciones. Si el caso de insensibilidad es necesario, elimine mayúsculas o minúsculas de los caracteres de la cadena y se generará 35^3 (42,875) valores únicos.

    Puede ser fácilmente adaptado para que el primer carácter es siempre una carta, o todas las letras.

    No dobut puede ser optimizado, y también podría negarse a devolver un identificador cuando se alcanza el límite.

    var nextId = (function() {
      var nextIndex = [0,0,0];
      var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
      var num = chars.length;
    
      return function() {
        var a = nextIndex[0];
        var b = nextIndex[1];
        var c = nextIndex[2];
        var id = chars[a] + chars[b] + chars[c];
    
        a = ++a % num;
    
        if (!a) {
          b = ++b % num; 
    
          if (!b) {
            c = ++c % num; 
          }
        }
        nextIndex = [a, b, c]; 
        return id;
      }
    }());
  4. 2
    var letters = 'abcdefghijklmnopqrstuvwxyz';
    var numbers = '1234567890';
    var charset = letters + letters.toUpperCase() + numbers;
    
    function randomElement(array) {
        with (Math)
            return array[floor(random()*array.length)];
    }
    
    function randomString(length) {
        var R = '';
        for(var i=0; i<length; i++)
            R += randomElement(charset);
        return R;
    }
    • por favor explique la razón por la downvoting una correcta y elegante respuesta, aunque no downvoting otro similar respuesta, gracias
    • Yo no la vote, pero estoy casi dispuesto a dar a otro simplemente por el with(Math) maldad 🙂
    • Creo que with tiene el potencial de ser utilizado sin problema en la no ejecución de código, y que el «with es el MAL» es fácilmente llevado al extremo. =) No es el rendimiento de un factor (si es que simplemente no lo uso), ni la creación o clobbering las variables de un problema (no las asignaciones se hacen), ni es la confusión con un global de las variables de un problema aquí. Prefiero tomar un pequeño impacto en el rendimiento que tiene que redefinir todo el módulo de Matemáticas en el ámbito global.
    • en realidad no importa, me di cuenta de que si uno hace with (Math) y uno define una variable var max = ... entonces uno va a sobrescribir Math.max……… bien, no utilizando with más
    • Yo realmente no se preocupan por el rendimiento de la misma, es más los matices de la misma, y el hecho de que usted tendrá que ir a buscar anteriores líneas de código con el fin de determinar qué floor y random en realidad se refieren a
  5. 2

    Que esto va a generar una secuencia de valores únicos. Mejora en RobG la respuesta de crecimiento de la longitud de la cuerda cuando todos los valores han sido exhaused.

    var IdGenerator = (function () {
    
        var defaultCharset = "[email protected]#$%^&*()_-+=[]{};:?/.>,<|".split("");
    
        var IdGenerator = function IdGenerator(charset) {
            this._charset = (typeof charset === "undefined") ? defaultCharset : charset;
            this.reset();
        };
    
        IdGenerator.prototype._str = function () {
            var str = "",
                perm = this._perm,
                chars = this._charset,
                len = perm.length,
                i;
            for (i = 0; i < len; i++) {
                str += chars[perm[i]];
            }
            return str;
        };
    
        IdGenerator.prototype._inc = function () {
            var perm = this._perm,
                max = this._charset.length - 1,
                i;
            for (i = 0; true; i++) {
                if (i > perm.length - 1) {
                    perm.push(0);
                    return;
                } else {
                    perm[i]++;
                    if (perm[i] > max) {
                        perm[i] = 0;
                    } else {
                        return;
                    }
                }
            }
        };
    
        IdGenerator.prototype.reset = function () {
            this._perm = [];
        };
    
        IdGenerator.prototype.current = function () {
            return this._str();
        };
    
        IdGenerator.prototype.next = function () {
            this._inc();
            return this._str();
        };
    
        return IdGenerator;
    
    }).call(null);

    Uso:

    var g = new IdGenerator(),
        i;
    
    for (i = 0; i < 100; i++) {
       console.log(g.next());
    }

    Esta esencia contiene la implementación y una versión recursiva.

  6. 0

    acaba de generar aleatoriamente algunas cadenas:

    function getUID(len){
        var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
              out = '';
    
        for(var i=0, clen=chars.length; i<len; i++){
           out += chars.substr(0|Math.random() * clen, 1);
        }
    
        //ensure that the uid is unique for this page
        return getUID.uids[out] ? getUID(len) : (getUID.uids[out] = out);
    }
    getUID.uids = {};
    • Parece ineficaz para generar al azar cadenas, a continuación, tiene que probar para ver si ellos son únicos. Es bastante simple para generar cadenas de caracteres (donde único tiene algún ámbito o contexto), ya sea con o sin generado aleatoriamente componente mediante un simple contador.
    • Las probabilidades de que uno de estos no único es absurdamente bajo, si usted está generando 6-teclas de dígitos (hay 56.8 millones de claves únicas con este). Hay casi nunca será un choque así que no hay casi nunca será re-generación.
    • ¿por qué salir de alguna oportunidad cuando simplemente se puede evitar? Y por qué generar un valor que deben verificarse para la singularidad cuando se puede generar un garantizado valor único en el primer lugar?
    • debido a que el OP no quiere «000», «001», … «00z», «00A», … y la generación de estos al azar es la simple forma de evitar eso. Incluso si usted fuera a hash ellos, usted todavía necesita básicos de la detección de colisiones de hash. También, estos pueden ser utilizados entre la carga de la página, etc. en el que caso de que no desee iniciar siempre en 1. Mi argumento general es que si el OP solo quiere un guid para la página, un simple contador funciona bien. Desde que el OP no se puede pedir para un contador, proporcionando una base-62 contador no es que útil.
    • El OP puede generar el número requerido de los Identificadores y al azar se les asigne, de modo que no secuencial (no se especifica en la pregunta, pero tal vez sea necesario).
    • Y que mejor que un 1/5.6 millones de posibilidades de re-generación de una clave, ¿cómo? 🙂 Yo todavía sostienen que si el OP quiere ‘guid’, generando secuencial de las teclas no es una buena solución. Pero no importa, OP problema 🙂

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea