Udało mi się dokonać konwersji. Trudną rzeczą jest to, że nie jest to tylko mieszana konwersja bazowa, wyższa baza pierwszego znaku wpływa również na wartości dłuższych kodów.
Zacząłem od łatwiejszego przypadku; kody base-10. Widziałem, że zakres dwucyfrowy ma 10 dodatkowych kodów, zakres trzycyfrowy ma 100 dodatkowych kodów i tak dalej:
0 - 9 : '0' - '9'
10 - 109 : '00' - '99'
110 - 1109 : '000' - '999'
1110 - 11109 : '0000' - '9999'
Tak więc wartość pierwszego znaku w kodzie nie jest tylko podstawą podniesioną do pozycji, ale ma również offset.
Po zastosowaniu tego do kodowania base-62, oto, na czym skończyłem:
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