2011-04-05 20 views
3

(此算法适用于我正在开发的iPhone应用程序,如果这有助于上下文的话)。如何智能地将任意元数据编码到UUID中?

我们需要使UUID唯一标识某些产品。通常这与分配唯一号码一样简单,但我们也希望将元数据编码到我们的UUID中。我们的API只允许我们使用一个字段,因此我们希望将UUID字段用作唯一标识符和元数据载体。

通常情况下,您可以将数据与下划线一起大杂烩,但是我们有一个要求使得难度更大:其中一个元数据项可以是n项的列表。

这里是元数据:

  • 设备类型(〜多达16种离散的类型)
  • 闵OS版本支持的(XXX格式,其中x为0-99之间的数字)
  • 敏二进制(应用程序)版本支持(XXX格式,其中x是0-99之间的数字)
  • 的任何产品,该产品取代版本(的ñ的ID列表,其格式是这样的设计问题的一部分)

限制

我们唯一的技术限制是,我们只能使用多达128个字母数字字符(A-ZA-Z0-9),包括下划线,句号和连字符,来表示UUID(这是一个API)。

使用案例

这里有几个用例来解释一下这个算法将有助于解决:

  1. 用户购买产品A和产品B后来我们推出的产品C,其是一个产品A + B包装在一起。通过C的UUID,我们希望我们的应用程序代码能够确定C实际上是A + B,并且由于用户已经拥有A + B,因此C不会出现在可用产品列表中。

  2. 用户有2个设备A和B.设备B不支持产品C,因此当用户在设备B上查看产品时,C不应该对设备B可用,但它应该在设备A上。

什么我因此完成远

设备类型应了解快速与16种离散类型,I可以位掩码 - 16位= 4个十六进制字符。够简单。

版本控制是相同的 - 我可以将每个版本段(x.y.z)填充到2位数,然后只有2个6位数的运行版本信息。

不重要的是如何引用以前的产品ID。显然,我的记忆空间有限 - 我只有128个字符(使用上述方法,我只剩下112个字符)。如果我需要ñ项目的列表,我用完空间。

实际上n < = 5是合理的。任何给定的产品将取代不超过5个其他产品。

固定长度的UUID不是必需的。是的,一个“便宜”的解决方案是将ID列表与下划线菊花链连接起来,但由于许多ID必须首先手动输入,因此我们希望避免使用128个字节(如果可以的话)躲开它。在算法的正确性之后,最小化UUID长度应该是优先级。

另一部分可能会使这种困难 - 虽然这不是UUID本身,而是代码中的实现 - 是如果其中一个被取代的产品取代了别的东西,则需要级联。

任何指针我可以在这里开始?

+0

您可以使用1个十六进制字符对16种类型进行编码。 – bdares 2011-04-05 07:01:13

+0

@bdares,等等。我认为你是对的,但后来我意识到我希望能够说“这个产品支持这16个设备的任何SUBSET”,而不仅仅是16个中的1个。在后一种情况下,你是对的。那么,编码“16的X”类型(其中X <= 16)所需的最小空间是多少? – makdad 2011-04-05 07:02:04

+0

1个十六进制字符可以是0-9,A,B,C,D,E,F ...,它们是16.如果每个字符代表1种设备,则设备可以用1个十六进制标识其类型字符。 – bdares 2011-04-05 07:15:05

回答

1

想想十进制或十六进制数字是一个坏主意,它只是浪费太多空间。

您的UUID字母表有65个(2 * 26 + 10 + 3)个字符。所以用n个字符可以编码65^n个不同的值。 例如,x.x.x格式(其中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。

+0

你是对的,用你在这里说的方法我可以节省一些空间。我也同意你将ID分成两部分。我去做!你有没有对最后一部分的建议,被取代的ID?我想拥有一个可以取代另一个ID的ID作为自己的ID,这就是我遇到麻烦的地方。有什么帮助吗? – makdad 2011-04-06 00:08:56

+0

使用替代列表中的短ID,您不需要那里的元数据。我不知道所有的要求,但是这解决了两个用例。我错过了什么吗? – 2011-04-06 09:45:07

+0

我重新读你说的话,我想我明白你的观点。因此,UUID可能如下所示:(设备等元数据)+(短UUID)+(引用其他UUID) – makdad 2011-04-07 04:06:48

1

这个数据是否需要人类可读?

如果没有,那么也许你应该看看这个作为串行化结构/对象到一个字节数组128

例如,你可以使用的格式的最大长度的问题(UID [INT], Device [byte],ArrayLength [byte],ProductID01 [int16],...),然后将所得到的字节数组与base64进行比较。或者,如果您发布此数据并且不需要URL安全,那么只需将它作为char数组发送(基本上是base256)。我不知道你的限制,但你可以根据最大范围调整数据类型。例如,如果您认为数组长度永远不会大于16,那么您可以为DeviceType和ArrayLength分割一个字节。

更好的是使用像protoBuf这样的serlization框架。但我不知道它是否已经移植到iOS。

+0

伟大的问题。是的,最好是数据的人类可读性。也就是说,我总是可以编写一个shell脚本,或者在用户回答问题后“吐出”UUID。最好能够看到一个UUID并得到它的一般概念。 我的确喜欢base64的概念,因为当product_ids处于人们可以看到它们的位置时(它是一个API),它可以掩盖底层格式。 谢谢。 – makdad 2011-04-06 00:06:53

相关问题