Como gerar UUIDs "seguros para o idioma"?

20

Eu sempre quis usar seqüências de caracteres geradas aleatoriamente para os IDs dos meus recursos, para poder ter URLs mais curtos como este: / user / 4jz0k1

Mas nunca o fiz, porque estava preocupado com a geração aleatória de cadeias criando palavras reais, por exemplo: / user / f * cker. Isso traz dois problemas: pode ser confuso ou até ofensivo para os usuários, e também pode interferir no SEO.

Então pensei que tudo o que eu precisava fazer era estabelecer um padrão fixo, como adicionar um número a cada 2 letras. Fiquei muito satisfeito com o meu método 'generate_safe_uuid', mas percebi que era melhor apenas para SEO e pior para os usuários, porque aumentava a proporção de palavras reais geradas, por exemplo: / user / g4yd1ck5

Agora, estou pensando em criar um método 'replace_numbers_with_letters' e verificar se ele não formou nenhuma palavra em um dicionário ou algo assim.

Alguma outra ideia?

ps. Enquanto escrevia isso, também percebi que procurar palavras em mais de um idioma (por exemplo: inglês e francês, espanhol etc.) seria uma bagunça, e estou começando a amar IDs apenas com números novamente.

ATUALIZAR

Alguns links que todos devem ler:

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

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

HappyDeveloper
fonte
Use um hash ou soma de verificação? Se você preferir usar uma sequência aleatória, não há regra para usar todas as letras do alfabeto.
Austin Henley
21
Não chame isso de uuid, uuid são identificadores universalmente únicos. Refere-se a um sistema específico de identificadores que você pode usar. Não é isso que você está fazendo aqui, então não use esse termo.
Winston Ewert
4
Eu só vai deixar você com o conto do gerador automático Curse
Scott Chamberlain
1
@ HappyDeveloper, em primeiro lugar, não é universal. É específico para sua aplicação. Em segundo lugar, uuid refere-se especificamente a en.wikipedia.org/wiki/Universally_unique_identifier e não a nenhum esquema semelhante que você planeja.
Winston Ewert
2
Este é um desperdício incrível de braintime. As chances de isso realmente está acontecendo é muito pequeno demais para valer a pena sequer pensar ...
Michael Borgwardt

Respostas:

6

Algumas dicas que reduzirão as chances de criar palavras significativas inadvertidamente:

  • Adicione alguns caracteres não alfa e não numéricos à mistura, como "-", "!" ou "_".
  • Componha seus UUIDs acumulando seqüências de caracteres (em vez de caracteres únicos) que dificilmente ocorrerão em palavras reais, como "zx" ou "aa".

Este é um código de exemplo do C # (usando o .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();  
}  

Isso não garante que você não ofenda ninguém, mas eu concordo com o @DeadMG que você não pode ter um objetivo tão alto.

CesarGon
fonte
1
O problema com os não alfanuméricos é que alguns deles não devem ter um bom desempenho em URIs (levando a caracteres escapados, que são um grande não-não em um URL minúsculo: há um motivo pelo bit.ly e tinyurl não os usarem). A outra questão é que eles são menos intuitivos para o usuário: não são fáceis, digamos, escrever em um post-it ou transmitir por telefone (muitos não-técnicos não têm idéia do nome do sublinhado, por exemplo exemplo). Mais uma vez, há uma razão pela qual url pequeno e bit.ly não os estão usando.
user988052
@ user988052: Daí alguns caracteres não alfa e não numéricos. É fácil selecionar alguns que sejam bons para URIs e fáceis o suficiente para humanos.
CesarGon
"Daí alguns caracteres não alfa, não numéricos." [sic] ... os serviços de encurtamento de URL (bit.ly, tinyurl, t.co, goo.gl etc.) parecem pensar que zero não-alfanumiano é melhor que "alguns". E acho que as razões que expliquei em meus comentários anteriores fazem parte da explicação de por que esses serviços não estão de acordo com o seu ponto de vista. Agora, obviamente, nossas opiniões divergem sobre o assunto e deixarei a última palavra; )
user988052
@ user988052: uso goo.gl há muito tempo e nunca houve problema em converter todos os tipos de caracteres não-alfa; a única exceção sendo%. Você pode encontrar isso documentado no grupo de discussão do serviço. Você pode fornecer qualquer referência que faça backup de suas reivindicações?
CesarGon
1
OP afirmou que queria nomes curtos e pede um método para gerá-los. Você sugere "adicionar caracteres não-alfa e não-numéricos à mistura" [sic]. Então o que você está sugerindo? Esse OP primeiro gera "alguma coisa" e depois envia para tinyurl / bit.ly? Eu acho que não é isso que OP é depois. O OP deseja gerar diretamente uma URL que seja relativamente "pequena". Tudo o que estou dizendo é que, se é isso que ele procura, pode ser melhor ele usar um alfabeto alfanum, exatamente como tinyurl / bit.ly está fazendo! Agora estou mesmo de folga.
user988052
5

Basta criar uma lista de palavras impertinentes, uma lista de substituição de letras e, se qualquer ID gerado for uma palavra impertinente, refaça-a.

Por exemplo (pseudo có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))

(Você pode consultar outras recomendações de URL curtas como esta para obter informações sobre hash / conversão na base 62)

Agora você não recebe mais códigos como a55,sh1t ou "b00bs". Sua lista de substituição de letras só precisa conter caracteres em suas palavras maliciosas, obviamente.

Uma vez que ninguém vai ler "455" como "bunda", então você pode também querer return stremreducestring se ele não contém qualquer letra.

Exemplos

O site de design gráfico Dribbble possui seus próprios IDs de cadeia curta para postagens. Estes usam 0-9, az e AZ como http://drbl.in/dCWi .

Eu fiz algumas experiências e há identificações curtas para pelo menos algumas palavras maliciosas. Acho que veremos quando chegarem f, mas ainda não estão lá.

Concedido - dar a um usuário seu próprio URL de identificação pessoal ( /user/whatever) em vez de apenas uma postagem é muito pior com palavras maliciosas.

Nicole
fonte
2
Certa vez, escrevi um programa que gerava senhas para um serviço online. Eles eram aleatórios, mas havia algumas heurísticas que os tornavam meio pronunciáveis, para que fossem lembrados com mais facilidade. E essas heurísticas levaram a palavrões. A solução foi a seguinte: verifique se há substratos vulgares, incluindo aqueles que possam ser pronunciados de maneira semelhante a palavras vulgares (por exemplo, procure FUC e FUK) e gere novamente a senha. (Para risos, o programa escreveu as senhas rejeitados para um arquivo separado.)
Kindall
1
E como você vai escrever uma coisa dessas para todas as línguas ?
DeadMG
1
@DeadMG Para o conjunto completo de todas as palavras ofensivas possíveis, isso só pode torná-lo menor. A sua posição é realmente: "porque você não pode alcançar 100%, automaticamente não vale a pena fazer nada"?
1155 Nicole
E o UTF-8? Existem muitos caracteres alternativos para impressão que contornam essa substituição.
JBWilkinson
1
@JBRWilkinson que não se aplica porque o OP está definindo o conjunto de caracteres alfanuméricos para IDs, certo?
Nicole
5

Considere usar uma chave numérica ou hexadecimal. Isso poupará muitos problemas, em comparação com a criação de um filtro de palavrões compatível com i18n, e o pior com o qual você precisará se preocupar é com a carne morta .

Comunidade
fonte
1
+1: Eu acho que essa é a solução mais simples e segura. Você pode gerar um uuid na forma de um número e usar uma representação de string para ele (decimal, hexadecimal, octal).
Giorgio
4
Você ainda precisa se preocupar com B16B00B5: P
CodesInChaos
3

Você nunca pode impedir que um sistema automatizado gere uma sequência ofensiva para um usuário. Por exemplo, na China, alguns números são considerados azarados.

Tudo o que você pode fazer é dizer ao usuário que seu ID é aleatório e que o conteúdo é irrelevante e, se receberem /user/fucker, deve ignorá-lo. Essas coisas acontecem e não é tecnicamente viável evitá-lo - assim como você nunca pode filtrar palavrões.

DeadMG
fonte
9
Eu não sou o defensor do voto negativo, mas sinto muito fortemente que, por palavras ofensivas, você realmente precisa fazer muito, muito, muito melhor do que "dizer a eles que eles devem simplesmente ignorá-lo". O mínimo que você pode fazer é oferecer uma maneira de alterar o ID gerado para um que eles considerem aceitável.
Marjan Venema
4
Eu não sou o downvoter qualquer um, mas eu concordo com @MarjanVenema, / user / f * cker não é aceitável
HappyDeveloper
@ HappyDeveloper: Como sugeri anteriormente, o que você fará sobre isso? Você não pode impedir que os usuários recebam IDs que considerem ofensivos.
DeadMG
3
@DeadMG Você pode ajudar a situação impedindo alguns casos geralmente ofensivos . Eu pensei que a pergunta original deixou isso bem claro.
7264 Nicole
2
@NickC: Os únicos exemplos são geralmente ofensivos em inglês . Você tem alguma idéia do que é geralmente ofensivo em árabe, português, chinês e russo? Sem mencionar o fato de que esses idiomas podem ter palavrões que assumem muitas formas. É fácil, caso especial, as formas óbvias das palavras em inglês, mas não é tão fácil fazê-lo para todos.
DeadMG
2

Existem basicamente duas estratégias que você pode empregar:

  1. Crie um sistema que não gere seqüências ofensivas. Por exemplo, você pode compor seus IDs apenas a partir de letras consoantes. Ao omitir todas as vogais, você pode ter certeza de que seu sistema nunca gerará nenhuma palavra em inglês, travessa ou não.

  2. Após gerar um ID completamente aleatório, verifique se o novo ID não inclui substrings ofensivos.

Caleb
fonte
1

Em muitas situações (spam de email, bloqueio de ip etc.), uma lista negra é um jogo perdido - você nunca poderá criar uma lista negra "completa" de todas as possíveis coisas ruins que possam ocorrer. a b c d e f

Muitas pessoas usam uma lista de permissões de palavras aceitáveis ​​e as agrupam em alguma ordem aleatória. (Talvez com um traço ou ponto ou espaço entre cada palavra).

Alguns dicionários populares usados ​​para converter números arbitrários em uma série pronunciável de palavras incluem:

David Cary
fonte
0

Você pode torná-lo apenas números gerados aleatoriamente ou ter um regex para cancelar os que são ofensivos:

/ass/ =~ userid
/boobs/ =~ userid
/morenaughtywordshere/ =~ userid
Billjk
fonte
2
Engraçado, porque eu nunca pensaria nisso como ofensivo.
DeadMG
Eu sei ... É um assunto delicado para postar palavrões reais em um site SE: meta.stackexchange.com/questions/22232/...
Billjk