Как правильно кодировать произвольные метаданные в UUID? - PullRequest
3 голосов
/ 05 апреля 2011

(Этот алгоритм предназначен для приложения для iPhone, над которым я работаю, если это вообще помогает контексту.)

Нам нужно создать UUID для уникальной идентификации некоторых продуктов.Обычно это так же просто, как присвоение уникальных номеров, но мы также хотим закодировать метаданные в наш UUID.Наш API позволяет нам только ОДНО поле, поэтому мы хотим использовать поле UUID в качестве уникального идентификатора и носителя метаданных.

Обычно вы можете просто объединить данные вместе с подчеркиванием, но у нас есть однотребование, которое делает это трудным: один из элементов метаданных может быть списком из n элементов.

Вот метаданные:

  • Тип устройства (~ вверхдо 16 дискретных типов)
  • Поддерживается минимальная версия ОС (формат xxx, где x - число от 0 до 99)
  • Поддерживается минимальная бинарная версия (приложение) (формат xxx, где x - эточисло между 0-99)
  • Любые продукты, которые заменяет этот продукт (список n идентификаторов, формат которых является частью этой проблемы дизайна)

Ограничения

Наше единственное техническое ограничение заключается в том, что мы можем использовать до 128 буквенно-цифровых символов (a-zA-Z0-9), включая подчеркивания, точки и дефисы, для представления UUID(это API).

Варианты использования

Вот несколько вариантов использования, чтобы объяснить, что этот алгоритм поможет решить:

  1. Пользователь покупает продукт A и продукт B. Позже мы выпустим продукт C, который представляет собой пакет.продуктов А + Б вместе.Через UUID C мы хотим, чтобы код нашего приложения мог определить, что C действительно является A + B, а поскольку пользователь уже владеет A + B, C не будет отображаться в списке доступных продуктов.

  2. У пользователя есть 2 устройства, A и B. Продукт C не поддерживается на устройстве B, поэтому, когда пользователь просматривает продукты на устройстве B, C не должен быть доступен для них, но он должен быть на устройстве A.

Что я уже сделал

Тип устройства должен быть простым - с 16 дискретными типами, я могу установить битовую маску - 16 бит =4 шестнадцатеричных символа.Достаточно просто.

Управление версиями одинаково - я могу дополнить каждый сегмент версии (xyz) до 2 цифр, а затем просто получить 2 серии по 6 цифр в качестве информации о версии.

Где этонетривиально, как ссылаться на предыдущие идентификаторы продукта.Ясно, что объем моей памяти ограничен - у меня всего 128 символов (и, используя описанные выше подходы, у меня осталось всего 112 символов)Если мне нужен список из n элементов, у меня будет нехватка места.

Реально n <= 5 </em> разумно.Любой данный продукт заменит не более 5 других продуктов.

UUID фиксированной длины НЕ является требованием.И да, одно «дешевое» решение состоит в последовательном добавлении списка идентификаторов вместе с подчеркиванием, но поскольку многие идентификаторы необходимо вводить вручную, мы бы хотели избежать использования 128 байтов, если сможемизбегай это.Минимизация длины UUID должна быть приоритетом после корректности в алгоритме.

Другая часть, которая может усложнить это - хотя реализация этого не в самом UUID, а скорее в коде - заключается в том, чтоесли один из замененных продуктов заменял что-то другое, то это должно каскадно идти вниз.

Есть какие-нибудь указатели на то, где я могу начать с этого?

Ответы [ 2 ]

1 голос
/ 05 апреля 2011

Должны ли эти данные быть удобочитаемыми для человека ???

Если нет, то, возможно, вам следует рассмотреть это как проблему сериализации структуры / объекта в байтовый массив с максимальной длиной 128.

Например, вы можете использовать формат (UID [int], Device [byte], ArrayLength [byte], ProductID01 [int16], ...), затем взять полученный байтовый массив и base64 его.Или, если вы публикуете эти данные, и они не обязательно должны быть безопасными для URL, просто отправьте их как массив символов (в основном base256).Я не знаю ни одного из ваших пределов, но вы можете настроить типы данных на основе максимальных диапазонов.Например, если вы думаете, что длина массива никогда не будет больше 16, то вы можете разделить байт для DeviceType и ArrayLength.

Еще лучше было бы использовать инфраструктуру серлизации, такую ​​как protoBuf.Но я не знаю, был ли он портирован на iOS.

1 голос
/ 05 апреля 2011

Мышление в терминах десятичных или шестнадцатеричных цифр - плохая идея, оно просто тратит слишком много места.

Ваш алфавит 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.

...