Уникальный случайный идентификатор, использующий все 62 символа - PullRequest
0 голосов
/ 27 марта 2019

Я ищу способ генерировать уникальные случайные идентификаторы, которые будут максимально короткими (аналогично сокращителям URL) либо с помощью кода, либо с использованием MSSQL (предпочтительно).

Я знаю, что это можно сделать с помощьюNEWID или CRYPT_GEN_RANDOM (), но эти методы используют только AF и 0-9, в то время как я ищу решение, которое будет использовать все 62 символа (AZ, az, 0-9) и, следовательно, получить гораздо более короткий идентификатор.

1 Ответ

0 голосов
/ 27 марта 2019

Я не могу сказать, что это подходящая задача для SQL Server, но, тем не менее, она достижима.

Во-первых, вам нужно создать таблицу сопоставления, которая содержит все символы, которые вы хотите видеть в своих URL-адресах.:

declare @charmap table (
  Id tinyint identity(0,1) primary key,
  Letter char(1) collate Latin1_General_BIN not null unique
);

insert into @charmap (Letter)
select top (26) char(row_number() over(order by (select null)) - 1 + ascii('A'))
from sys.all_objects ao
union all
select top (26) char(row_number() over(order by (select null)) - 1 + ascii('a'))
from sys.all_objects ao
union all
select top (10) char(row_number() over(order by (select null)) - 1 + ascii('0'))
from sys.all_objects ao;

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

Теперь следующий запрос сгенерирует указанное количество кодов, имеющих одинаковую желаемую длину.Первые две переменные определяют, что:

declare @BatchSize int = 1000,
  @Length int = 7;

select h.RndHex,
  replace(
    (select cm.Letter as [data()] from (
      select top (datalength(h.RndHex)) row_number() over(order by (select null)) as [RN]
      from sys.all_objects ao
    ) ca
    inner join @charmap cm on cm.Id = cast(substring(h.RndHex, ca.RN, 1) as tinyint) % 62
    order by ca.RN
    for xml path('')
    ), ' ', ''
  ) as [ShortURL]
from (
  select top (@BatchSize) crypt_gen_random(@Length) as [RndHex]
  from sys.all_objects a, sys.all_objects o
) h;

Технически, 5 символов дадут вам power(62., 5) ~ = 916 миллионов уникальных комбинаций.Однако вы можете увеличить длину кода, чтобы их было сложнее угадать.Вот почему мой пример генерирует 7-символьные коды - для 100 миллионов использованных комбинаций он предоставит около 35000 возможных комбинаций для каждой фактически сгенерированной.

С другой стороны, если угадывание не является проблемой дляВы можете хранить как минимум длину кодов, которая в вашем случае составляет 5 символов.

...