title: How to smartly encode arbitrary metadata into a UUID?
body: <p>(This algorithm is for an iPhone app I am working on, if that helps the context at all.)</p>
  
  <p>We need to make UUIDs to uniquely identify some products.  Usually this is as simple as assigning unique numbers, but we also want to encode metadata INTO our UUID.  Our API only allows us ONE field, so we want to use the UUID field as both a unique identifier and a metadata carrier.</p>
  
  <p>Usually, you can just hodge-podge the data together with underscores, but we have one requirement that makes this difficult: one of the metadata items can be a list of <em>n</em> items.</p>
  
  <p>Here is the metadata:</p>
  
  <ul>
  <li>Device type (~up to 16 discrete types)</li>
  <li>Min OS version supported (x.x.x format, where x is a number between 0-99)</li>
  <li>Min Binary (app) version supported (x.x.x format, where x is a number between 0-99)</li>
  <li>Any products that this product supersedes (list of <em>n</em> IDs, the format of which is part of this design problem)</li>
  </ul>
  
  <p><strong>Limitations</strong></p>
  
  <p>Our only technical limitation is that we can only use up to 128 alphanumeric characters (a-zA-Z0-9), including underscores, periods, and hyphens, to represent the UUID (it's an API).</p>
  
  <p><strong>Use Cases</strong></p>
  
  <p>Here are a few use cases to explain what this algorithm will help solve:</p>
  
  <ol>
  <li><p>A user buys product A and product B.  We later release product C, which is a package of products A+B together.  Via C's UUID, we want our application code to be able to determine that C is really A+B, and since the user already owns A+B, C will not appear on a list of available products.</p></li>
  <li><p>A user has 2 devices, A and B.  Product C is not supported on device B, so when the user views products on device B, C should not be available to them, but it should be on device A.</p></li>
  </ol>
  
  <p><strong>What I've Done Thus Far</strong></p>
  
  <p>Device type should be easy- with 16 discrete types, I can bitmask that - 16 bits = 4 hex characters.  Simple enough.</p>
  
  <p>Versioning is the same - I can pad each version segment (x.y.z) to 2 digits, and then just have 2 runs of 6 digits as the version information.</p>
  
  <p>Where it is non-trivial is how to refer to previous product IDs.  Clearly, my memory space is limited - I only have 128 characters (and using the approaches above, I'd have only 112 characters left).  If I need a list of <em>n</em> items, I <em>will</em> run out of space.</p>
  
  <p>Realistically <em>n&lt;=5</em> is reasonable.  Any given product would supersede no more than 5 other products.</p>
  
  <p>A fixed-length UUID is NOT a requirement.  And yes, one "cheap" solution is to daisy-chain the ID list together with underscores, but since many of the IDs will have to be hand-entered in the first place, we'd like to avoid using 128 bytes if we can avoid it.  Minimizing the UUID length should be a priority after correctness in the algorithm.</p>
  
  <p>Another part that may make this difficult -- although the implementation of this isn't in the UUID itself but rather in the code -- is that if one of the superseded products was superseding something else, that needs to cascade down.</p>
  
  <p>Any pointers on where I can start on this?</p>