2010-04-29 93 views
0

我正在製作一個URL縮短器,並且我正在努力將編號(id)編碼爲字符串的最佳方式。多基轉換 - 使用URL縮短器的所有組合

我使用字符0-9,A-Z,a-z,所以它基本上是一個基本的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, ... 

這將是基62和基地63的組合,與根據位置不同的基礎...使用基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('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', @UrlId % 62 + 1, 1) + @Code 
    set @UrlId = @UrlId/62 
end 

select @Code 

但我還沒有設法做出一個多基地轉換出來,利用所有的代碼。

+3

你所有的基地都屬於我們。 – 2010-04-29 21:07:51

+0

@Byron:你是什麼意思? 0將是'0',10將是'A',35將是'Z',61將是'z',62將是'00',63將是'01'等等。 – Guffa 2010-04-29 21:21:01

+0

你是對的我誤解了這個問題。 – 2010-04-29 21:51:05

回答

4

我設法進行了轉換。棘手的是,它不僅僅是一個混合基地轉換,第一個字符的較高基數也會影響較長代碼的值。

我從一個更簡單的案例開始;基地10代碼。我看到這兩個數字範圍內有10個額外的代碼,三位數的範圍內有100個多碼,依此類推:

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

所以,在代碼中的第一個字符的價值不只是提高到基地的位置,但它也有一個偏移量。

將其應用到基礎-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 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' 
    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