Я должен генерировать GUID и сохранить его через строковое представление. Строковое представление должно быть максимально коротким, поскольку оно будет использоваться в качестве части уже длинной строки URL.
Прямо сейчас, вместо того, чтобы использовать нормальный abcd-efgh-... представление, я использую необработанные сгенерированные байты и base64-кодирую их вместо этого, который приводит к несколько более короткой строке.
Но действительно ли возможно сделать его еще короче?
Я соглашаюсь с потерей определенной степени уникальности и хранения счетчика, но сканирование всех существующих ключей не является опцией. Предложения?
Конечно, просто используйте базу больше 64. Вам придется закодировать их, используя собственный алфавит, но вы сможете найти еще несколько «безопасных для URL» печатаемых символов ASCII.
Base64 кодирует 6 бит, используя 8, поэтому значение GUID из 16 байтов становится закодированным в 22 байта. Вы можете уменьшить это значение на один или два символа, но не более того.
Я не уверен, что это осуществимо, но вы могли бы поместить все сгенерированные GUID в таблицу и использовать в URL только индекс GUID в таблице.
Вы также можете уменьшить длину GUID - например, использовать 2 байта для указания количества дней с 2010 года и 4 байта для количества милисекунд с начала текущего дня. Столкновения будут только для двух GUID, сгенерированных за одну и ту же милисекунду. Вы также можете добавить еще 2 случайных байта, что сделает это еще лучше.
Можно подойти к этому с другой стороны. Создать максимально короткое представление строки и отобразить его в Guid.
Генерировать ключ, используя определенный алфавит, как показано ниже:
В psuedocode:
string RandomString(char[] alphabet, int length)
{
StringBuilder result = new StringBuilder();
for (int i = 0; i < length; i++)
result.Append(alphabet[RandomInt(0, alphabet.Length)]);
return result;
}
Если длина строки не превышает 16, можно просто закодировать результат шестнадцатеричным кодом и передать его конструктору Guid для разбора.