使用所有62个字符的唯一随机ID

时间:2019-03-27 06:21:34

标签: sql sql-server random guid newid

我正在寻找一种通过代码或使用MSSQL(优选)来生成尽可能短(类似于url缩短器)的唯一随机ID的方法。

我知道可以使用NEWID或CRYPT_GEN_RANDOM()来完成此操作,但是这些方法仅使用AF和0-9,而我正在寻找一种将使用所有62个字符(AZ,az,0-9)和因此获得一个短得多的ID。

1 个答案:

答案 0 :(得分:0)

我不能说这对于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;

从技术上讲,五个字符将为您提供power(62., 5)〜= 9.16亿个唯一组合。但是,您可能希望增加代码长度,以使其更难猜测。这就是为什么我的示例生成7个字符的代码-对于使用的1亿个组合,每实际生成的组合将提供大约35000个可能的组合。

另一方面,如果您不希望出现可猜测性,则可以将代码的长度保持在最小(在您的情况下为5个字符)。