(这个算法适用于我正在开发的 iPhone 应用程序,如果这对上下文有帮助的话。)
我们需要制作UUID来唯一标识一些产品。通常这就像分配唯一编号一样简单,但我们还希望将元数据编码到我们的 UUID 中。我们的 API 只允许使用一个字段,因此我们希望使用 UUID 字段作为唯一标识符和元数据载体。
通常,您可以将数据与下划线混合在一起,但我们有一个要求使这一点变得困难:元数据项之一可以是包含n 个项的列表。
这是元数据:
局限性
我们唯一的技术限制是,我们只能使用最多 128 个字母数字字符 (a-zA-Z0-9),包括下划线、句点和连字符来表示 UUID(它是一个 API)。
用例
以下是一些用例来解释该算法将帮助解决什么问题:
用户购买了产品A和产品B。后来我们发布了产品C,它是产品A+B的组合。通过C的UUID,我们希望我们的应用程序代码能够确定C确实是A+B,并且由于用户已经拥有A+B,所以C不会出现在可用产品列表中。
用户有 2 个设备,A 和 B。设备 B 不支持产品 C,因此当用户在设备 B 上查看产品时,C 不应该对他们可用,而应该在设备 A 上。
到目前为止我所做的
设备类型应该很简单 - 有 16 种离散类型,我可以对其进行位掩码 - 16 位 = 4 个十六进制字符。够简单的。
版本控制是相同的 - 我可以将每个版本段 (xyz) 填充为 2 位数字,然后只需 2 次 6 位数字作为版本信息。
重要的是如何引用以前的产品 ID。显然,我的内存空间是有限的 - 我只有 128 个字符(使用上面的方法,我只剩下 112 个字符)。如果我需要一个包含n 个项目的列表,我将耗尽空间。
实际上n<=5是合理的。任何给定产品将取代不超过 5 个其他产品。
固定长度的 UUID 不是必需的。是的,一个“便宜”的解决方案是将 ID 列表与下划线菊花链在一起,但由于许多 ID 必须首先手动输入,因此我们希望尽可能避免使用 128 字节躲开它。在算法正确性之后,应优先考虑最小化 UUID 长度。
另一个可能使这变得困难的部分——尽管它的实现不是在 UUID 本身中而是在代码中——是如果一个被取代的产品正在取代其他产品,则需要级联下来。
有关于我可以从哪里开始的任何指示吗?
用十进制或十六进制数字来思考是一个坏主意,它只会浪费太多空间。
您的 UUID 字母表有 65 (2*26+10+3) 个字符。因此,使用 n 个字符,您可以编码 65^n 个不同的值。例如,xxx 格式(其中 x 是 0-99 之间的数字)实际上只有 100^3 个不同的值,因此可以使用 log65(100^3) ~ 3.31 = 4 个字符进行编码。因此,对于前三个元数据,您需要 1+4+1=9 个字符,或者如果您组合三个字段 log65(100^3*100^3*16) ~ 7.28 = 8 个字符。
对于产品取代级联问题,我建议将 UUID 分为两部分,第一部分包含短 UUID,第二部分包含元数据。当您引用被取代的产品时,请使用短 UUID。