Короткие URL в .NET. Начало
Короткие URL - простой, но мощный инструмент, преобразующий длинные URL в более удобные и короткие. Два популярных инструмента сокращения URL-адресов — Bitly и TinyURL. Посмотрим, как создать его самому.
Нам нужны 2 конечные точки:
- Генерирующая уникальный кода для данного URL,
- Перенаправляющая с короткой ссылки, на исходный URL.
URL будут храниться в БД.
Длина кода и набор символов определяют, сколько коротких URL может сгенерировать система. Для генерации будем использовать Random, т.к. его легко реализовать, и он имеет приемлемо низкий уровень коллизий.
Модель данных
ShortUrl представляет URL, хранящиеся в нашей системе:
public class ShortUrl
{
public Guid Id { get; set; }
public string Url { get; set; }
public string Code { get; set; }
public DateTime CreatedOn { get; set; }
}
Класс включает исходный URL (Url) и уникальный код (Code), представляющий сокращённый URL. Id и CreatedOn используются для БД и отслеживания.
В AppDbContext настроим сущность и контекст БД:
- Максимальную длину кода,
- Уникальный индекс на столбце Code, чтобы в БД не было повторяющихся значений кода.
- Также некоторые БД обрабатывают строки без учета регистра. Это значительно уменьшает количество доступных коротких URL. Нужно настроить БД для обработки уникального кода с учетом регистра:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions opts)
: base(options)
{ }
public DbSet<ShortUrl> ShortUrls { get; set; }
protected override void
OnModelCreating(ModelBuilder mb)
{
mb.Entity<ShortUrl>(b =>
{
b.Property(u => u.Code)
.HasMaxLength(ShortLinkSettings.Length);
b.HasIndex(u => u.Code)
.IsUnique();
});
}
}
Генерация уникального кода
Есть несколько алгоритмов реализации. Мы хотим равномерного распределения уникальных кодов по всем возможным значениям. Это поможет уменьшить коллизии. Здесь рассмотрим генератор случайного кода с предопределённым алфавитом. Его просто реализовать, и вероятность коллизий относительно невелика. ShortLinkSettings содержит две константы - длину кода и алфавит:
public static class ShortLinkSettings
{
public const int Length = 7;
public const string Alphabet =
"ABCDEF…xyz01…89";
}
В алфавите 62 символа, что даёт больше 3х триллионов(!!!) уникальных комбинаций.
UrlShorteningService генерирует уникальные коды. Мы выбираем случайные символы из алфавита до достижения длины, а затем проверяем, нет ли уже такого кода в БД. Если нет, возвращаем его, если есть, повторяем процесс:
public class UrlShorteningService(AppDbContext ctx)
{
private Random _rnd = new();
public async Task<string> GetCode()
{
const len = ShortLinkSettings.Length;
var chars = new char[len];
const int maxVal =
ShortLinkSettings.Alphabet.Length;
while (true)
{
for (var i = 0; i < len; i++)
{
var idx = _rnd.Next(maxVal);
chars[i] =
ShortLinkSettings.Alphabet[idx];
}
var code = new string(chars);
if (!await ctx.ShortUrls.AnyAsync(
s => s.Code == code))
return code;
}
}
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/how-to-build-a-url-shortener-with-dotnet