Как генерировать «безопасные для языка» UUID?

20

Я всегда хотел использовать случайно сгенерированные строки для идентификаторов своих ресурсов, поэтому я мог бы использовать более короткие URL, например: / user / 4jz0k1

Но я никогда этого не делал, потому что беспокоился о генерации случайных строк, создающих реальные слова, например: / user / f * cker. Это создает две проблемы: это может сбивать с толку или даже оскорблять пользователей, а также может портить SEO.

Тогда я подумал, что все, что мне нужно было сделать, это установить фиксированный шаблон, например, добавить число каждые 2 буквы. Я был очень доволен своим методом «generate_safe_uuid», но потом я понял, что он был только лучше для SEO и хуже для пользователей, потому что он увеличил соотношение фактических генерируемых слов, например: / user / g4yd1ck5

Теперь я думаю, что мог бы создать метод replace_numbers_with_letters и убедиться, что в нем нет слов против словаря или чего-то еще.

Есть еще идеи?

пс. Когда я писал это, я также понял, что проверка слов на более чем одном языке (например, на английском и французском, испанском и т. Д.) Будет беспорядком, и я снова начинаю любить идентификаторы, состоящие только из цифр.

ОБНОВИТЬ

Некоторые ссылки, которые каждый должен прочитать:

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

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

HappyDeveloper
источник
Использовать хэш или контрольную сумму? Если вы предпочитаете использовать случайную строку, нет никакого правила, что вы должны использовать каждую букву в алфавите.
Остин Хенли
21
Не называйте это uuid, uuid являются универсально уникальными идентификаторами. Это относится к конкретной системе идентификаторов, которые вы можете использовать. Это не то, что вы делаете здесь, так что не используйте этот термин.
Уинстон Эверт
4
Я просто оставлю вас с рассказом об автоматическом генераторе проклятий
Скотт Чемберлен
1
@HappyDeveloper, во-первых, не универсален. Это специфично для вашего приложения. Во-вторых, uuid конкретно ссылается на en.wikipedia.org/wiki/Universally_unique_identifier, а не на любую подобную схему, которую вы разработали.
Уинстон Эверт
2
Это такая невероятная трата мозгового времени. Шансы на то, что это действительно произойдет, слишком малы, чтобы о них даже можно было подумать ...
Майкл Боргвардт,

Ответы:

6

Несколько советов, которые снизят вероятность непреднамеренного создания значимых слов:

  • Добавьте в смесь несколько не-буквенных нечисловых символов, таких как «-», «!» или "_".
  • Составьте свои UUID, накапливая последовательности символов (а не отдельных символов), которые вряд ли встречаются в реальных словах, таких как «zx» или «aa».

Вот пример кода C # (с использованием .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();  
}  

Это не гарантирует, что вы никого не обидите, но я согласен с @DeadMG, что вы не можете стремиться так высоко.

CesarGon
источник
1
проблема с не алфавитно-цифровыми заключается в том, что некоторые из них не должны хорошо воспроизводиться в URI (что приводит к экранированному символу, который является большим «нет-нет» в крошечном URL: есть причина, по которой bit.ly и tinyurl их не используют). Другая проблема заключается в том, что они менее интуитивно понятны для пользователя: им нелегко, скажем, записать на почту или передать по телефону (многие нетехнические специалисты не имеют ни малейшего представления, как называется подчеркивание, так как пример). Еще раз есть причина, почему крошечные URL и bit.ly не используют их.
user988052
@ user988052: Отсюда некоторые не буквенные, не числовые символы. Легко выбрать несколько, которые подходят для URI и достаточно легко для людей.
CesarGon
«Следовательно, некоторые не-альфа, не числовые символы». [sic] ... Сервисы сокращения URL-адресов (bit.ly, tinyurl, t.co, goo.gl и т. д.), похоже, считают, что нулевой не алфавит лучше, чем «некоторые». И я думаю, что причины, которые я объяснил в моих предыдущих комментариях, являются частью объяснения того, почему эти службы не согласны с вашей точкой зрения. Теперь, очевидно, наши мнения расходятся по этому вопросу, и я оставлю вам последнее слово; )
user988052
@ user988052: я использовал goo.gl целую вечность, и у него никогда не было проблем с преобразованием всех видов не-буквенных символов; единственное исключение -%. Вы можете найти это документально в дискуссионной группе службы. Можете ли вы предоставить какие-либо ссылки, подтверждающие ваши претензии?
CesarGon
1
ОП заявил, что ему нужны короткие имена, и просит метод для их создания. Вы предлагаете "добавить сына, не альфа, не числовые символы в смесь" [sic]. Так что ты предлагаешь? Этот OP сначала генерирует «что-то», а затем отправляет это в tinyurl / bit.ly? Я думаю, что это не то, что после ОП. ОП хочет напрямую генерировать относительно небольшой URL. Все, что я говорю, это то, что если он хочет этого, ему лучше использовать алфавитный алфавит, как это делает tinyurl / bit.ly! Теперь я действительно выключен.
user988052
5

Просто создайте список непослушных слов, список замены букв, а затем, если какой-либо сгенерированный идентификатор является непослушным словом, повторите его.

Например (псевдокод)

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))

(Вы можете обратиться к другим рекомендациям по коротким URL-адресам, таким как эта, для получения информации о хешировании / преобразовании базы 62)

Теперь вы больше не получаете идентификаторы нравится a55, sh1tили «b00bs». Очевидно, ваш список замены букв должен содержать только символы в ваших непослушных словах.

Так как никто не будет читать «455» , как «жопу» , то вы также можете return strв , reducestringесли она не содержит никаких писем.

Примеры

Сайт графического дизайна Dribbble имеет собственные короткие строковые идентификаторы для постов. Они используют 0-9, az и AZ, например http://drbl.in/dCWi .

Я провел некоторые эксперименты, и есть короткие идентификаторы, по крайней мере, для нескольких непослушных слов. Я думаю, мы увидим, когда они доберутся f, но они еще не там.

Конечно, предоставление пользователю собственного идентифицирующего URL-адреса ( /user/whatever) вместо простого сообщения намного хуже с непослушными словами.

Николь
источник
2
Однажды я написал программу, которая генерировала пароли для онлайн-сервиса. Они были случайными, но было несколько эвристик, которые делали их произносимыми, так что их было бы легче запомнить. И эта эвристика привела к ненормативной лексике. Решение было таким, как описано здесь: проверьте наличие вульгарных подстрок, в том числе тех, которые могут произноситься аналогично вульгарным словам (например, ищите FUC и FUK), и восстановите пароль. (Для хихиканья программа записала отклоненные пароли в отдельный файл.)
kindall
1
И с какой стати ты собираешься написать такую ​​вещь для каждого языка ?
DeadMG
1
@DeadMG Для полного набора всех возможных оскорбительных слов, это может только сделать этот набор меньше. Действительно ли ваша позиция: «потому что вы не можете достичь 100%, автоматически ничего не стоит делать»?
Николь
А как насчет UTF-8? Есть много альтернативных печатных символов, которые обходят эту замену.
JBRWilkinson
1
@JBRWilkinson, который не применяется, потому что OP устанавливает набор буквенно-цифровых символов для идентификаторов, верно?
Николь
5

Попробуйте вместо этого использовать цифровой или шестнадцатеричный ключ. Это избавит вас от многих проблем по сравнению с написанием фильтра ненормативной лексики с поддержкой i18n, и самое страшное, о чем вам придется беспокоиться, это мертвая говядина .

Сообщество
источник
1
+1: я думаю, что это самое простое и безопасное решение. Вы можете сгенерировать uuid в виде числа и использовать для него строковое представление (десятичное, шестнадцатеричное, восьмеричное).
Джорджио
4
Вы все еще должны беспокоиться о B16B00B5: P
CodesInChaos
3

Вы никогда не сможете запретить автоматической системе генерировать какую-либо строку, которая оскорбительна для пользователя. Например, в Китае некоторые цифры считаются несчастливыми.

Все, что вы действительно можете сделать, это сказать пользователю, что его идентификатор является случайным, а содержимое не имеет значения, и если они его получат, /user/fuckerему следует просто проигнорировать его. Эти вещи случаются, и технически просто невозможно избежать этого - точно так же, как вы никогда не сможете отфильтровать ненормативную лексику.

DeadMG
источник
9
Я не отрицатель, но я чувствую очень сильно, что для оскорбительных слов вам действительно нужно сделать намного, намного, намного лучше, чем «сказать им, что они должны просто игнорировать это». Самое меньшее, что вы могли бы сделать, - это предложить какой-то способ изменить сгенерированный идентификатор на тот, который они считают приемлемым.
Марьян Венема
4
Я тоже не даунтер, но я согласен с @MarjanVenema, / user / f * cker недопустим
HappyDeveloper
@HappyDeveloper: Как я уже говорил, что вы собираетесь с этим делать? Вы не можете запретить пользователям получать идентификаторы, которые они считают оскорбительными.
DeadMG
3
@DeadMG Вы можете помочь ситуации, предотвратив несколько обычно оскорбительных случаев. Я думал, что оригинальный вопрос прояснил это.
Николь
2
@NickC: Единственные примеры обычно оскорбительны на английском языке . У вас есть идеи, что обычно оскорбляет арабский, португальский, китайский, русский? Не говоря уже о том, что у этих языков могут быть ругательства, которые принимают множество форм. Легко специально выделить очевидные формы слов из английского, но не так просто сделать это для всех.
DeadMG
2

По сути, вы можете использовать две стратегии:

  1. Создайте систему, которая не будет генерировать никаких оскорбительных строк. Например, вы можете составить свой идентификатор только из согласных букв. Опуская все гласные, вы можете быть уверены, что ваша система никогда не будет генерировать английские слова, непослушные или нет.

  2. После генерации совершенно случайного идентификатора убедитесь, что новый идентификатор не содержит оскорбительных подстрок.

Калеб
источник
1

Во многих ситуациях (спам по электронной почте, блокировка ip и т. Д.) Черный список - игра проигрышная - вы никогда не сможете создать «полный» черный список всех возможных плохих вещей, которые могут когда-либо произойти. а б в г е ф

Многие люди используют белый список приемлемых слов и объединяют их в случайном порядке. (Возможно, с тире или точкой или пробелом между каждым словом).

Некоторые популярные словари, которые используются для преобразования произвольных чисел в произносимые серии слов, включают в себя:

Дэвид Кэри
источник
0

Вы можете сделать это просто случайно сгенерированными числами или использовать регулярные выражения, чтобы отменить оскорбительные:

/ass/ =~ userid
/boobs/ =~ userid
/morenaughtywordshere/ =~ userid
Billjk
источник
2
Забавно, потому что я никогда не думал об этом как обидном.
DeadMG
Я знаю ... Это просто тема для публикации реальных ругательств на сайте SE: meta.stackexchange.com/questions/22232/…
Billjk