Jag lyckades göra omställningen. Det knepiga är att det inte bara är en blandad baskonvertering, den högre basen för det första tecknet påverkar också värdena för längre koder.
Jag började med ett lättare fall; bas-10-koder. Jag såg att det tvåsiffriga intervallet har 10 extra koder, det tresiffriga intervallet har 100 extra koder, och så vidare:
0 - 9 : '0' - '9'
10 - 109 : '00' - '99'
110 - 1109 : '000' - '999'
1110 - 11109 : '0000' - '9999'
Så, värdet på det första tecknet i koden är inte bara basen upphöjd till positionen, utan den har också en offset.
Efter att ha tillämpat detta på bas-62-kodningen, är det detta jag slutade med:
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