1

URL 短縮サービスを作成していますが、数値 (id) を文字列にエンコードする最適な方法に苦労しています。

文字 0-9、AZ、az を使用しているため、基本的に base-62 エンコーディングになります。これはかなり基本的なことですが、考えられるすべてのコードを利用しているわけではありません。生成されるコードは次のとおりです。

0, 1, ... y, z, 10, 11, ... zy, zz, 100, 101, ...

コード 00 から 0z は使用されないことに注意してください。000 から 0zz も同様です。次のように、すべてのコードを使用したいと思います。

0, 1, ... y, z, 00, 01, ... zy, zz, 000, 001, ...

base-62 と base-63 の組み合わせで、位置に応じて異なる base になります... base-62 の使用は簡単です。たとえば、次のようになります。

create procedure tiny_GetCode
    @UrlId int
as
set nocount on

declare @Code varchar(10)
set @Code = ''

while (@UrlId > 0 or len(@Code) = 0) begin
    set @Code = substring('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', @UrlId % 62 + 1, 1) + @Code
    set @UrlId = @UrlId / 62
end

select @Code

しかし、すべてのコードを利用するために、それを多塩基変換することはまだできていません。

4

1 に答える 1

4

私はなんとか変換を行うことができました。トリッキーなことは、それが単なる混基変換ではなく、最初の文字のより高いベースもより長いコードの値に影響を与えるということです。

私はもっ​​と簡単なケースから始めました。10進数のコード。2桁の範囲には10個の追加コードがあり、3桁の範囲には100個の追加コードがあることがわかりました。

0 - 9        : '0' - '9'
10 - 109     : '00' - '99'
110 - 1109   : '000' - '999'
1110 - 11109 : '0000' - '9999'

したがって、コードの最初の文字の値は、その位置まで上げられたベースだけでなく、オフセットもあります。

これをbase-62エンコーディングに適用した後、これが私が最終的に得たものです。

create function tiny_Encode(@UrlId int) returns varchar(10)
as
begin

  declare
    @Chars varchar(62),
    @Code varchar(10),
    @Value int,
    @Adder int

  set @Chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
  if (@UrlId < 63) begin
    set @Code = substring(@Chars, @UrlId, 1)
  end else begin
    set @UrlId = @UrlId - 1
    set @Value = 62
    set @Adder = 0
    while (@UrlId >= @Value * 63 + @Adder) begin
      set @Adder = @Adder + @Value
      set @Value = @Value * 62
    end
    set @Code = substring(@Chars, (@UrlId - @Adder) / @Value, 1)
    set @UrlId = ((@UrlId - @Adder) % @Value)
    while (@Value > 1) begin
      set @Value = @Value / 62
      set @Code = @Code + substring(@Chars, @UrlId / @Value + 1, 1)
      set @UrlId = @UrlId % @Value
    end
  end
  return @Code

end
于 2010-04-30T11:58:02.953 に答える