¿Cómo generar UUID "seguros para el idioma"?

20

Siempre quise usar cadenas generadas aleatoriamente para las ID de mis recursos, por lo que podría tener URL más cortas como esta: / user / 4jz0k1

Pero nunca lo hice, porque me preocupaba que la generación de cadenas al azar creara palabras reales, por ejemplo: / user / f * cker. Esto trae dos problemas: puede ser confuso o incluso ofensivo para los usuarios, y también puede afectar el SEO.

Luego pensé que todo lo que tenía que hacer era establecer un patrón fijo como agregar un número cada 2 letras. Estaba muy contento con mi método 'generate_safe_uuid', pero luego me di cuenta de que solo era mejor para SEO y peor para los usuarios, porque aumentaba la proporción de palabras reales que se generaban, por ejemplo: / user / g4yd1ck5

Ahora estoy pensando que podría crear un método 'replace_numbers_with_letters', y verificar que no haya formado ninguna palabra contra un diccionario o algo así.

¿Alguna otra idea?

PD. Mientras escribo esto, también me di cuenta de que buscar palabras en más de un idioma (por ejemplo: inglés y francés, español, etc.) sería un desastre, y estoy empezando a amar las identificaciones solo de números nuevamente.

ACTUALIZAR

Algunos enlaces que todos deberían leer:

http://thedailywtf.com/Articles/The-Automated-Curse-Generator.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2008/06/27/8659071.aspx

HappyDeveloper
fuente
¿Utiliza un hash o suma de verificación? Si prefiere usar una cadena aleatoria, no hay ninguna regla de que tenga que usar todas las letras del alfabeto.
Austin Henley
21
No lo llames uuid, los uuid son identificadores universales únicos. Se refiere a un sistema específico de identificadores que puede usar. Eso no es lo que estás haciendo aquí, así que no uses ese término.
Winston Ewert
44
Te dejaré con la historia del generador automático de maldiciones
Scott Chamberlain
1
@HappyDeveloper, en primer lugar, no es universal. Es específico para su aplicación. En segundo lugar, uuid se refiere específicamente a en.wikipedia.org/wiki/Universally_unique_identifier y no a ningún esquema similar que usted haya ideado.
Winston Ewert
2
Este es un desperdicio increíble de braintime. Las posibilidades de que suceda realmente es demasiado pequeña para que valga la pena siquiera pensar en ...
Michael Borgwardt

Respuestas:

6

Un par de consejos que reducirán las posibilidades de crear palabras significativas sin darse cuenta:

  • Agregue algunos caracteres no alfa, no numéricos a la mezcla, como "-", "!" o "_".
  • Componga sus UUID acumulando secuencias de caracteres (en lugar de caracteres individuales) que es poco probable que ocurran en palabras reales, como "zx" o "aa".

Este es un código de muestra de C # (usando .NET 4):

private string MakeRandomString()  
{  
    var bits = new List<string>()  
    {  
            "a",  
            "b",  
            "c",  
            "d",  
            "e",  
            //keep going with letters.  
            "0",  
            "1",  
            "2",  
            "3",  
            //keep going with numbers.  
            "-",  
            "!",  
            "_",  
            //add some more non-alpha, non-numeric characters.  
            "zx",  
            "aa",  
            "kq",  
            "jr",  
            "yq",  
            //add some more odd combinations to the mix.  
    };  

    StringBuilder sb = new StringBuilder();  
    Random r = new Random();  
    for (int i = 0; i < 8; i++)  
    {  
        sb.Append(bits[r.Next(bits.Count)]);  
    }  

    return sb.ToString();  
}  

Esto no garantiza que no ofenderás a nadie, pero estoy de acuerdo con @DeadMG en que no puedes apuntar tan alto.

CesarGon
fuente
1
El problema con los no alfanuméricos es que algunos de ellos no funcionarán bien en los URI (lo que lleva a un carácter escapado, que es un gran no-no en una URL pequeña: hay una razón con bit.ly y tinyurl no los están usando). El otro problema es que son menos intuitivos para el usuario: no es fácil, por ejemplo, escribir en un post-it o transmitir por teléfono (muchos no expertos en tecnología no tienen idea de cuál es el nombre del guión bajo, para ejemplo). Una vez más, hay una razón por la cual tiny url y bit.ly no los están usando.
user988052
@ user988052: De ahí algunos caracteres no alfa, no numéricos. Es fácil seleccionar algunos que estén bien para los URI y lo suficientemente fácil para los humanos.
CesarGon
"De ahí algunos caracteres no alfa, no numéricos". [sic] ... los servicios de acortamiento de URL (bit.ly, tinyurl, t.co, goo.gl, etc.) parecen pensar que cero no alfanumérico es mejor que "algunos". Y creo que las razones que expliqué en mis comentarios anteriores son parte de la explicación de por qué estos servicios no están de acuerdo con su punto de vista. Ahora, obviamente, nuestras opiniones son diferentes al respecto y les dejaré la última palabra; )
user988052
@ user988052: He estado usando goo.gl durante años y nunca tuve problemas para convertir todo tipo de caracteres no alfa; la única excepción es%. Puede encontrar esto documentado en el grupo de discusión del servicio. ¿Puede proporcionar alguna referencia que respalde sus reclamos?
CesarGon
1
OP declaró que quería nombres cortos y solicita un método para generarlos. Sugiere "agregar caracteres no alfa, no numéricos a la mezcla" [sic]. Entonces, ¿qué estás sugiriendo? ¿Ese OP primero genera "algo" y luego lo envía a tinyurl / bit.ly? Creo que eso no es lo que busca OP. OP quiere generar directamente una URL que sea relativamente "pequeña". Todo lo que digo es que si eso es lo que está buscando, ¡entonces puede ser mejor para él usar un alfabeto alfanumérico, como lo está haciendo tinyurl / bit.ly! Ahora estoy realmente fuera.
user988052
5

Simplemente cree una lista de palabras traviesas, una lista de sustitución de letras, y luego, si alguna ID generada es una palabra traviesa, vuelva a hacerla.

Por ejemplo (pseudocódigo)

naughty_words = ["ass", "shit", "boobs"]
substitutions = {
    "4" : "a"
    "1" : "i"
    "3" : "e"
    "7" : "t"
    "5" : "s"
    "0" : "o"
    // etc.
}

function reducestring (str) {
    newstr = ""
    for (character in str) {
        if (substitituions[character]) newstr += substitutions[character]
        else newstr += character
    }
    return tolower(newstr)
}

do {
    new_id_numeric = random_number()
    short_id = compress_to_alphanumeric(new_id_numeric) // 0-9, a-z, A-Z
    // that function should create a base 62 number
} while (!contains(naughty_words, reducestring(short_id))

(Puede consultar otras recomendaciones de URL cortas como esta para obtener información sobre el hash / conversión de base 62)

Ahora ya no recibe identificaciones les gusta a55, sh1to "b00bs". Su lista de sustitución de letras solo necesitaría contener caracteres en sus palabras traviesas, obviamente.

Puesto que nadie va a leer "455" como "culo", entonces también puede ser que desee return stren reducestringcaso de que no contiene ninguna letra.

Ejemplos

El sitio de diseño gráfico Dribbble tiene sus propios identificadores de cadena cortos para publicaciones. Estos usan 0-9, az y AZ como http://drbl.in/dCWi .

Experimenté un poco y hay identificadores cortos para al menos algunas palabras traviesas. Supongo que ya veremos cuando lleguen f, pero todavía no están allí.

Por supuesto, dar a un usuario su propia url de identificación personal ( /user/whatever) en lugar de solo una publicación es mucho peor con palabras traviesas.

Nicole
fuente
2
Una vez escribí un programa que generaba contraseñas para un servicio en línea. Eran aleatorios, pero había algunas heurísticas que los hacían bastante pronunciables, por lo que serían más fáciles de recordar. Y estas heurísticas condujeron a blasfemias. La solución fue como se describe aquí: verifique las subcadenas vulgares, incluidas las que se pueden pronunciar de manera similar a las palabras vulgares (por ejemplo, busque FUC y FUK) y vuelva a generar la contraseña. (Para las risas, el programa escribió las contraseñas rechazadas en un archivo separado.)
poco el
1
¿Y cómo demonios vas a escribir algo así para cada idioma ?
DeadMG
1
@DeadMG Para el conjunto completo de todas las palabras ofensivas posibles, esto solo puede hacer que ese conjunto sea más pequeño. ¿Es realmente su postura: "porque no puede alcanzar el 100%, automáticamente no vale la pena hacer nada"?
Nicole
¿Qué pasa con UTF-8? Hay muchos caracteres imprimibles alternativos que evitan esta sustitución.
JBRWilkinson
1
@JBRWilkinson que no se aplica porque el OP está configurando el conjunto de caracteres de caracteres alfanuméricos para ID, ¿verdad?
Nicole
5

Considere usar una clave numérica o hexadecimal en su lugar. Le ahorrará muchos problemas en comparación con escribir un filtro de blasfemias compatible con i18n, y lo peor de lo que tendrá que preocuparse es carne muerta .

Comunidad
fuente
1
+1: Creo que esta es la solución más simple y segura. Puede generar un uuid en forma de número y usar una representación de cadena para él (decimal, hexadecimal, octal).
Giorgio
44
Todavía tiene que preocuparse por B16B00B5: P
CodesInChaos
3

Nunca puede evitar que un sistema automatizado genere una cadena que sea ofensiva para un usuario. Por ejemplo, en China algunos números se consideran desafortunados.

Todo lo que realmente puede hacer es decirle al usuario que su ID es aleatoria y que el contenido es irrelevante y, si lo obtienen /user/fucker, simplemente deben ignorarlo. Estas cosas suceden y no es técnicamente factible evitarlo, al igual que nunca se puede filtrar la blasfemia.

DeadMG
fuente
99
No soy el votante negativo, pero creo firmemente que para las palabras ofensivas realmente necesitas hacer mucho, mucho, mucho mejor que "decirles que deberían ignorarlo". Lo menos que puede hacer es ofrecer alguna forma de cambiar la identificación generada a una que consideren aceptable.
Marjan Venema
44
No soy el votante tampoco, pero estoy de acuerdo con @MarjanVenema, / user / f * cker no es aceptable
HappyDeveloper
@HappyDeveloper: Como sugerí anteriormente, ¿qué vas a hacer al respecto? No puede evitar que los usuarios reciban identificaciones que consideren ofensivas.
DeadMG
3
@DeadMG Puede ayudar a la situación previniendo algunos casos comúnmente ofensivos . Pensé que la pregunta original lo dejaba bastante claro.
Nicole
2
@NickC: Los únicos ejemplos son comúnmente ofensivos en inglés . ¿Tienes alguna idea de lo que comúnmente es ofensivo en árabe, portugués, chino y ruso? Sin mencionar el hecho de que esos idiomas pueden tener palabrotas que toman muchas formas. Es fácil destacar las formas obvias de las palabras del inglés, pero no es tan fácil hacerlo para todos.
DeadMG
2

Esencialmente, hay dos estrategias que puede emplear:

  1. Crea un sistema que no genere cadenas ofensivas. Por ejemplo, puede componer su identificación solo a partir de letras consonantes. Al omitir todas las vocales, puede estar seguro de que su sistema nunca generará palabras en inglés, traviesas o de otro tipo.

  2. Después de generar una identificación completamente aleatoria, verifique para asegurarse de que la nueva identificación no incluya ninguna subcadena ofensiva.

Caleb
fuente
1

En muchas situaciones (correo electrónico no deseado, bloqueo de IP, etc.), una lista negra es un juego perdido: nunca podrá hacer una lista negra "completa" de cada posible mal que pueda ocurrir. a b c d e f

Muchas personas usan una lista blanca de palabras aceptables y las unen en un orden aleatorio. (Quizás con un guión o punto o espacio entre cada palabra).

Algunos diccionarios populares que se utilizan para convertir números arbitrarios en una serie de palabras pronunciables incluyen:

David Cary
fuente
0

Puede hacerlo solo con números generados al azar, o tener una expresión regular para cancelar los que son ofensivos:

/ass/ =~ userid
/boobs/ =~ userid
/morenaughtywordshere/ =~ userid
Billjk
fuente
2
Es curioso, porque nunca pensaría en ninguno de esos como ofensivos.
DeadMG
Lo sé ... Es solo un tema delicado publicar palabras de maldición reales en un sitio de SE: meta.stackexchange.com/questions/22232/…
Billjk