Algorithm 如何巧妙地将任意元数据编码到UUID中?

Algorithm 如何巧妙地将任意元数据编码到UUID中?,algorithm,uuid,Algorithm,Uuid,(此算法适用于我正在开发的iPhone应用程序,如果这对上下文有帮助的话。) 我们需要制作UUID来唯一标识某些产品。通常这就像分配唯一的数字一样简单,但我们也希望将元数据编码到UUID中。我们的API只允许一个字段,因此我们希望将UUID字段用作唯一标识符和元数据载体 通常,您可以将数据与下划线放在一起,但我们有一个要求使得这很困难:其中一个元数据项可以是n个项的列表 以下是元数据: 设备类型(最多16种离散类型) 支持的最小操作系统版本(x.x.x格式,其中x是0-99之间的数字) 支持的

(此算法适用于我正在开发的iPhone应用程序,如果这对上下文有帮助的话。)

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

通常,您可以将数据与下划线放在一起,但我们有一个要求使得这很困难:其中一个元数据项可以是n个项的列表

以下是元数据:

  • 设备类型(最多16种离散类型)
  • 支持的最小操作系统版本(x.x.x格式,其中x是0-99之间的数字)
  • 支持的最小二进制(应用程序)版本(x.x.x格式,其中x是0-99之间的数字)
  • 本产品取代的任何产品(n个ID的列表,其格式是本设计问题的一部分)
限制

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

用例

以下是一些用例,以解释此算法将帮助解决的问题:

  • 用户购买产品A和产品B。我们稍后发布产品C,它是产品A+B的组合。通过C的UUID,我们希望我们的应用程序代码能够确定C实际上是A+B,并且由于用户已经拥有A+B,C将不会出现在可用产品的列表中

  • 一个用户有两个设备,A和B。设备B不支持产品C,因此当用户在设备B上查看产品时,C不应该对他们可用,但应该在设备A上

  • 到目前为止我所做的

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

    版本控制是相同的-我可以将每个版本段(x.y.z)填充为2位数字,然后只使用2行6位数字作为版本信息

    重要的是如何引用以前的产品ID。显然,我的内存空间是有限的——我只有128个字符(使用上述方法,我只剩下112个字符)。如果我需要n个项目的列表,我将用尽空间


    实际上,用十进制或十六进制数字来思考是个坏主意,它只会浪费太多的空间

    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。

    此数据是否需要人类可读

    如果不是,那么您可能应该将其视为将结构/对象序列化为最大长度为128的字节数组的问题

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


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

    YY您可以用一个十六进制字符来编码16种类型。@b战神,等等。我以为你是对的,但后来我意识到我想说“这个产品支持这16个设备中的任何一个子集”,而不仅仅是16个设备中的一个。在后一种情况下,你是对的。那么,编码“16个X”类型所需的最小空间是多少,其中X是1个十六进制字符,可以是0-9,A,B,C,D,E,F。。。它们是16个。如果每个字符代表一种设备类型,则设备可以用一个十六进制字符标识其类型。@b区域,正确。但我希望一个产品可以在其中的8个设备上工作,而不是其他8个。我在想是/否(2^16)=(2^4)^4的位掩码-因此我认为我需要四个字符。产品和设备之间不是一对一的关系。这是1比n,在这种情况下n=16,这是个好问题。是的,数据最好是人类可读的。也就是说,我总是可以编写一个shell脚本或在用户回答问题后“吐出”UUID的东西。最好能看到UUID并对其有一个大致的了解。我非常喜欢base64的想法,因为当产品ID位于人们可以查看的位置(它是一个API)时,它可以很好地隐藏底层格式。谢谢。你说得对,用你在这里说的方法我可以节省一些空间。我也同意你把身份证分成两部分。我会的!对于最后一部分,即被取代的ID,您有什么建议吗?我希望有一个ID可以取代另一个ID作为它自己的ID,所以这就是我遇到的问题。有什么帮助吗?使用替代列表中的短ID,您不需要那里的元数据。我不知道所有的需求,但这解决了两个用例。我错过了什么吗?我重新读了你说的话,我想我明白你的意思了。因此,UUID可能看起来像:(设备等元数据)+(短UUID)+(对其他UUID的引用)UUID的定义是递归的,因此如果您