如何生成“语言安全” UUID?


20

我一直想使用随机生成的字符串作为资源ID,因此我可以使用以下较短的URL:/ user / 4jz0k1

但是我从来没有这样做,因为我担心随机字符串的生成会产生实际的单词,例如:/ user / f * cker。这带来了两个问题:对用户而言可能令人困惑甚至令人反感,并且也可能与SEO混淆。

然后我想我所要做的就是建立一个固定的模式,例如每2个字母加一个数字。我对我的'generate_safe_uuid'方法感到非常满意,但是后来我意识到,它仅对SEO更好,对用户更糟,因为它增加了实际生成单词的比例,例如:/ user / g4yd1ck5

现在,我想我可以创建一个方法'replace_numbers_with_letters',并检查它是否未对字典或任何东西形成任何单词。

还有其他想法吗?

ps。在撰写本文时,我还意识到,检查一种以上语言(例如英语和法语,西班牙语等)中的单词将是一团糟,而我又开始喜欢仅数字的ID。

更新

每个人都应该阅读一些链接:

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

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


使用哈希或校验和?如果您喜欢使用随机字符串,则没有规则必须使用字母表中的每个字母。
奥斯丁·亨利

21
不要称它为uuid,uuid是普遍唯一的标识符。它是指可以使用的特定标识符系统。那不是您在这里所做的,所以不要使用该术语。
Winston Ewert'4


1
@HappyDeveloper,首先,它不是通用的。它特定于您的应用程序。其次,uuid专门指的是en.wikipedia.org/wiki/Universally_unique_identifier,而不是您设计的任何类似方案。
Winston Ewert'4

2
这真是令人难以置信的大脑浪费。实际发生的可能性太小,甚至不值得思考...
Michael Borgwardt 2012年

Answers:


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的观点,即您不能瞄准那么高的目标。


1
非字母数字的问题是其中一些字符在URI中的表现不佳(导致转义字符,这在一个很小的URL中是一个很大的禁忌:这是有原因的,bit.ly和tinyurl没有使用它们)。另一个问题是它们对用户的直观性较差:例如,在便利贴上写下文字或在电话上进行传送都不容易(许多非技术人员都不知道下划线的名称是什么,因为例)。再次有一个原因,为什么微小的url和bit.ly没有使用它们。
user988052 '04

@ user988052:因此,一些非字母,非数字字符。选择一些适合URI且对人类足够容易的方法很容易。
CesarGon 2012年

“因此,一些非字母,非数字字符。” [sic] ... URL缩短服务(bit.ly,tinyurl,t.co,goo.gl等)似乎认为非字母数字比“一些”更好。而且我认为我在之前的评论中解释的原因是有关这些服务为何与您的观点不一致的解释的一部分。现在很明显,我们在这件事上意见不一,我会留下最后的话; )
user988052 '04

@ user988052:我使用goo.gl已有很长时间了,转换各种非字母字符都没有问题;唯一的例外是%。您可以在服务的讨论组中找到此文档。您可以提供任何参考来支持您的主张吗?
CesarGon 2012年

1
OP表示他想要短名称,并要求一种生成短名称的方法。您建议“将儿子的非字母,非数字字符添加到组合中” [sic]。那你在暗示什么?该OP首先生成“内容”,然后将其发送到tinyurl / bit.ly?我认为这不是OP所追求的。OP希望直接生成相对“微小”的URL。我要说的是,如果那是他的追求,那么对他来说,使用alphanum字母可能会更好,就像tinyurl / bit.ly那样!现在我真的离开了。
user988052 '04

5

只需创建一个顽皮的单词列表,一个字母替换列表,然后如果生成的任何ID是一个顽皮的单词,请重做。

例如(伪代码)

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

(您可以参考其他类似这样的简短网址建议,以获取有关基于62哈希/转换的信息)

现在你不再获得的ID喜欢a55sh1t或“b00bs”。显然,您的字母替换列表仅需要在顽皮的单词中包含字符。

由于没有人会把“ 455”读为“ ass” return str,因此reducestring如果它不包含任何字母,您可能也想读入。

例子

图形设计网站Dribbble有自己的帖子短字符串ID。这些使用0-9,az和AZ等http://drbl.in/dCWi

我做了一些实验,至少有一些顽皮的单词都有简短的ID。我想我们会在他们到达时看到的f,但他们还没有到。

准许-为用户提供自己的个人身份url(/user/whatever)而不是仅发布帖子,用顽皮的话会更糟。


2
我曾经写过一个程序,该程序为在线服务生成密码。它们是随机的,但是有一些启发式方法可以使它们听起来很明显,因此更容易记住它们。这些启发法导致亵渎。解决方案如此处所述:检查低俗子字符串,包括那些可能与低俗单词发音类似的子字符串(例如查找FUC和FUK)并重新生成密码。(对于傻笑,该程序将拒绝的密码写到一个单独的文件中。)
kindall 2012年

1
那么,您将如何为每种语言编写这样的东西呢?
DeadMG

1
@DeadMG对于所有可能的冒犯性词语的完整集合,这只能使该集合变小。您的立场是否真的是:“因为您无法达到100%,所以不值得做任何事情”?
妮可·2012年

UTF-8呢?有很多替代的可打印字符可以解决这种替换问题。
JBRWilkinson '04年

1
@JBRWilkinson无效,因为OP正在为ID设置字母数字字符的字符集,对吗?
妮可

5

考虑改用数字或十六进制键。与编写可识别i18n的亵渎过滤器相比,这将为您节省很多麻烦,而您最担心的就是死牛肉


1
+1:我认为这是最简单,最安全的解决方案。您可以生成数字形式的uuid,并为其使用字符串表示形式(十进制,十六进制,八进制)。
Giorgio 2012年

4
您仍然需要担心B16B00B5:P
CodesInChaos

3

您永远都不能阻止自动化系统生成对用户有害的字符串。例如,在中国,一些数字被认为是不幸的。

您真正能做的就是告诉用户其ID是随机的,并且内容无关紧要,如果获得,/user/fucker则应该忽略它。这些事情发生了,避免这种情况在技术上不可行-就像您永远都无法过滤亵渎行为一样。


9
我不是拒绝投票的人,但我强烈感到,对于冒犯性的言语,您确实需要比“告诉他们他们应该忽略它”做得多很多。您至少可以做的是提供某种方式将生成的ID更改为他们认为可以接受的ID。
Marjan Venema

4
我也不是拒绝投票的人,但我同意@ MarjanVenema,/ user / f * cker是不可接受的
HappyDeveloper 2012年

@HappyDeveloper:正如我之前所建议的,您将如何处理?您不能阻止用户获得令人反感的ID。
DeadMG

3
@DeadMG您可以通过防止一些性的案件来帮助解决这种情况。我认为最初的问题很清楚。
妮可

2
@NickC:唯一的例子通常是令人反感的英语。您知道阿拉伯文,葡萄牙文,中文,俄文中最令人反感的是什么吗?更不用说这些语言的脏话可能采用许多种形式。对英语单词的明显形式进行特殊处理很容易,但对每个人来说却并非那么容易。
DeadMG

2

您基本上可以采用两种策略:

  1. 创建一个不会产生任何攻击性字符串的系统。例如,您可以仅由辅音字母组成ID。通过省略所有元音,可以确保您的系统永远不会生成任何顽皮或其他形式的英语单词。

  2. 生成完全随机的ID后,请检查以确保新ID不包含任何令人反感的子字符串。


1

在许多情况下(电子邮件垃圾邮件,IP阻止等),黑名单是一个失败的游戏-您将永远无法对可能发生的所有可能的坏事进行“完整”黑名单。 a b c d e f

许多人使用可接受单词的白名单,然后以某种随机顺序将它们串在一起。(也许每个单词之间都有破折号或点或空格)。

用于将任意数字转换为可发音的一系列单词的一些流行词典包括:


0

您可以将其设为随机生成的数字,也可以使用正则表达式来消除令人反感的数字:

/ass/ =~ userid
/boobs/ =~ userid
/morenaughtywordshere/ =~ userid

2
有趣,因为我从不认为这两种方法都是令人反感的。
DeadMG

我知道......这只是一个棘手的问题,以在SE网站上发布真正的骂人的话:meta.stackexchange.com/questions/22232/...
Billjk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.