如何智能地将任意元数据编码为UUID?

时间:2011-04-05 06:57:09

标签: algorithm uuid

(此算法适用于我正在处理的iPhone应用程序,如果这有助于上下文。)

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

通常情况下,您可以将数据与下划线一起提升,但我们有一个要求会使这一点变得困难:其中一个元数据项可以是 n 项目的列表。

以下是元数据:

  • 设备类型(〜最多16个离散类型)
  • 支持最低操作系统版本(x.x.x格式,其中x是介于0-99之间的数字)
  • 支持Min Binary(app)版本(x.x.x格式,其中x是介于0-99之间的数字)
  • 此产品取代的任何产品( n 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应该不可用,但它应该在设备A上

  3. 我迄今为止做了什么

    设备类型应该很简单 - 使用16种离散类型,我可以将其掩码--16位= 4个十六进制字符。很简单。

    版本控制是一样的 - 我可以将每个版本段(x.y.z)填充为2位数,然后只需要2次运行6位数作为版本信息。

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

    实际上 n< = 5 是合理的。任何给定的产品都不会超过5种其他产品。

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

    另一个可能使这个难以实现的部分 - 虽然这个实现不是在UUID本身而是在代码中 - 如果其中一个被取代的产品取代其他东西,那就需要级联。

    关于我可以从哪里开始的任何指示?

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:1)

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

如果没有,那么也许你应该把这看作是将结构/对象序列化为最大长度为128的字节数组的问题。

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

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