人类可读的 GUID

Posted

技术标签:

【中文标题】人类可读的 GUID【英文标题】:Human Readable GUID 【发布时间】:2010-12-27 22:14:18 【问题描述】:

我正在编写一个小系统,通过生成可在我们的网站上兑换 MP3 的优惠券,我可以在演出中出售我乐队的音乐。

代金券需要用户输入的代码。代码需要具有以下品质:

    在长度和内容方面具有一定程度的人类可读性,以防止用户感到沮丧和数据输入错误。 给定一个优惠券代码,猜测另一个优惠券代码并非易事。

如果我使用 GUID,我会担心第 1 点。如果我使用递增整数,我会担心第 2 点。两者之间必须有一些快乐的媒介,对吧?我想也许这项工作已经完成,并且有一个理想的解决方案在等着我。如果没有,我想我会使用随机的字母数字字符串,或者可能只有字母(为了清楚起见,不包括 I 和 O),并让应用程序阻止失败 X 次的 IP 地址,这表明可能的蛮力攻击。如果我这样做,字符串的长度和 X 的值会起作用,为什么?

感谢您的帮助!


更新:我并没有完全明确该方法:我将生成用于打印的优惠券代码列表,然后在演出后输入“已售”代码。因此,我认为校验和之类的元素没有必要,就像它们在不使用验证服务器的软件密钥中一样。

【问题讨论】:

关于阻止蛮力攻击,我不会费心开始。关于你和你的乐队,这并不是说你在保护一些非常重要的东西。这对我来说似乎有点不成比例。 你说得对,我在设计系统时玩得太开心了。但是你去吧,我本质上是一个程序员。另外,如果一切顺利,我可能会主持其他乐队的专辑。 他们正在保护他们的工作。请注意问题中的“出售”一词。 【参考方案1】:

您可以使用经过英语音节训练的马尔可夫链来创建一个由可发音的胡言乱语单词组成的句子。只需在打印时将生成的句子添加到有效凭证的数据库中(当然,在兑换时使它们失效)。

【讨论】:

您还可以使用某种形式的 N-gram 分析:它可能更容易理解和实现。 en.wikipedia.org/wiki/N-gram 我最后的评论有点混乱:N-gram 分析可以用来做“训练”部分。 如果你想避免“自动诅咒生成器”的问题,你可以用单词而不是音节来训练它。上周我用 C# 写了这样一个东西,给它喂了一本书分析之后,我吐出了“现在有多少人面临着外行教育”,“如果你不理解它会继续下去”之类的“句子”。情况”。【参考方案2】:

我会使用您自己的编码方案。除了省略 I 和 O,为了获得最佳可读性,在近同音词集(C/E、M/N)和多音节字母(例如 W)中省略一个字母以外的所有字母也是一个好主意,当然要坚持一个案例。

就长度而言,您可以使用 60 位,外加 4 位校验和。 64 位足以将时间以毫秒为粒度存储数千年,因此对于所有实际用途而言,它是不可猜测的。假设每个字母 4 位,即 16 个字母长。即使是这个长度的一半也可能足够了。

另一种思考方式是汽车牌照的形式:3 个字母和 3 个数字足以覆盖一个相当大的状态,并且往往非常易读。除非您为某人提供一种高速破解代码的方法,否则它们在人类时间尺度上肯定是不可猜测的。

【讨论】:

@RickNZ:Windows NTFS 和 OpenVMS 使用 64 位时间戳:两者都以每秒一千万次计。 NTFS 的年份范围为 1601 到 60,055,VMS 的年份范围为 1858 到 31,084。 (VMS 为相对时间目的保留范围的“负”一半。)【参考方案3】:

只有 8 个字母数字字母(I 和 O 除外)有 1785793904896 种可能的组合。只要您没有 50 亿张代金券,所有意图和目的都是不可猜测的。

【讨论】:

【参考方案4】:

AOL 过去常常使用两个词的随机组合来表示他们发送的 CD。您可以采用相同的方法,只需增加单词的数量即可获得所需的几率。

【讨论】:

我喜欢这个!来自this list 的三个单词和 4 个字母单词的键空间为 128,405,466,125... 非常可接受。【参考方案5】:

好吧,如果你真的想要人类可读,你可以使用BubbleBabble。创建一个 Perl 脚本,如下所示:

#!/usr/bin/perl
use Digest::BubbleBabble qw(bubblebabble);
use Digest::SHA1 qw(sha1);
print bubblebabble(Digest => sha1(join(' ', @ARGV))), "\n";

然后向它提供您想要获得输出的任何命令行参数,如下所示:

xogan-nydut-zogiv-kotyn-ledah-taseb-gyhib-tucel-vudul-mykom-mexax

或者,如果 Perl 不是您的偏好,您可以使用 PWGen (also available online 获得如下输出:

aiCee5om Ohxai2is tae3Gael Gaeth7ei ooCh0ish

老实说,这种程度的人类可读性是矫枉过正的; RickNZ 的答案应该可以正常工作(并且非常接近我们为某些软件密钥所做的)。但是 BubbleBabble 很有趣。

【讨论】:

@dreftymac 谢谢。 APG 似乎不再存在,因此我将其替换为 PWGen 的链接,这是一个类似的工具。【参考方案6】:

5 块,每块 5 个字符就足够了 - 四个块用于“密钥”,第五块作为校验和以确保有效性。当然,不要使用整个键空间。

无论如何,这就是软件序列号的大致布局方式。

【讨论】:

有趣,我从来不知道!但是,对于我的系统,这种算法并不直接适用,因为我将预先生成这些数字,然后在演出后“验证”我出售的代码。 它仍然适用——毕竟你不需要给出所有的代码。【参考方案7】:

嗯,我不知道大多数系统是如何工作的,但我认为定义一个静态数字并将该数字乘以一个随机的其他数字会很简洁。然后,如果大 GUID 是您的静态的倍数,那么您很好。

生产容易,新的不容易猜到(只限短期使用)

int i = 61234;
int j = rand()%99999
long GUID = i * j;

会给你一个电话号码长度的 GUID

虽然只有 99999 次使用!呵呵

【讨论】:

嗯,如果我不能达到 100,000 的销量,我们的专辑就不能成为白金!【参考方案8】:

最好避免所有元音[*],从而避免所有脏话。

[*] 如果你是威尔士人,包括 W!

【讨论】:

W 也是唯一的多音节字母,因此需要更长的时间才能说出(因此我非常不喜欢网站上的“www”!)。 还记得“旅行配音”吗?或者更糟糕的是,早在九十年代,你会在收音机里听到“aitch tee tee pee,colon,forward slash,forward slash,...” Rick:完全同意,有很多理由可以避免它!当你去掉所有的元音和所有容易出错的字母时,你会减少到大约 16 个,这对于每个字符来说正好是 4 位。【参考方案9】:

上下文

人类可读的 UUID 语言无关算法

问题

设计一种用于生成“人类可读”UUID (HR-UUID) 的算法 HR-UUID 应该能够抵御暴力猜测 人工输入和调用应该简单明了,不易出错 拥有 1 个或多个已知的有效 HR-UUID 在统计上与猜测其他有效 HR-UUID 无关

解决方案

使用DiceWare password algorithm。 与此线程中提供的其他解决方案相比,此方法通过将问题重新转换为密码生成问题来解决人类可读的 UUID 问题。 与此线程中其他地方提供的BubbleBabble 解决方案相比,Diceware 允许您选择每个 UUID 中包含多少元素,具体取决于您希望“掷骰子”的次数......这意味着您可以选择每个 UUID 的熵。 DiceWare 密码算法解决了生成高熵密码短语的问题,这些密码短语仍然易于人类输入和记忆。

以下是 Diceware “UUID”的示例,每个包含六个元素:

crabmeat-coach-properly-driving-yoga-ferret
edition-mousy-fabric-budding-book-mortuary
rickety-uncrown-earful-majority-sublet-evade

另见

XKCD comic promoting DiceWare algorithm Codenamize

【讨论】:

【参考方案10】:

一个简单的解决方案是调用大多数语言在其字符串类型上的 getHashCode 方法。将字符串设置为您批准的单词列表中的某个单词。然后调用 gethashcode 这将是你的关键。要验证它,请将其与您现有的单词哈希列表进行比较,并可能将其从列表中删除,使其无法再次使用。

【讨论】:

【参考方案11】:

我假设您在他们购买优惠券时会收到一个电子邮件地址(您应该)。如果是这样,为什么不通过电子邮件向他们发送一次性 GUID?这样你和他们都有记录,你可以跟踪兑换,你不会冒猜测的风险(或者至少不值得打扰),用户不必记住任何东西,因为它就在那里电子邮件,您无需编写任何代码。

他们会给你电子邮件地址。您通过电子邮件发送 GUID(带有链接)。他们点击链接并获取歌曲。 GUID 使用已在系统中注册,将不再有效。

【讨论】:

尽管我很想获得一份粉丝电子邮件地址列表,但我认为它会起到威慑作用。我们说的是凌晨 1:00 醉酒的 5 美元冲动购买,写下你的电子邮件地址真的可以抑制这种冲动。 好点!如果我喜欢不会阻止我的乐队,但我可能是例外而不是规则。【参考方案12】:

为什么不直接使用 GUID,然后用不同的字母替换任何有问题的字符(所以 0 变成 'h',1 是 'q' 等等)。

【讨论】:

【参考方案13】:

您可以尝试random letter sequence generator ? 之类的方法。您也可以混合和匹配字母/数字

【讨论】:

以上是关于人类可读的 GUID的主要内容,如果未能解决你的问题,请参考以下文章

将人类可读的日期从 Epoch 转换为变量

在 .htaccess 中启用人类可读的 URL

python人类可读的大数字[重复]

javascript 人类可读的字节数

php 人类可读的文件大小

JavaScript 人类可读的毫秒时间戳