using Base62; using Domain.AggregateModel.LinkAggregate; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace QRCodeService.Services { public class ShortCodeService : IShortCodeService { private readonly ILinkRepository linkRepository; public ShortCodeService(ILinkRepository linkRepository) { this.linkRepository = linkRepository; } public async Task GenShortCode(string url) { var full = 16; var length = 4; var idx = 0; while (true) { var code = CalculateShortCode(url, length, idx); var link = await linkRepository.GetAsync(code); if (link == null || link.FullUrl == url) { return code; } idx++; if (idx * length == full) { idx = 0; length = 2 * length; } } } /// /// 计算短链接 /// /// /// 4(四分之一) 8(半) 16(全长) /// /// private string CalculateShortCode(string url,int length,int index) { using (var md5 = MD5.Create()) { var result = md5.ComputeHash(Encoding.UTF8.GetBytes(url)); if (length == 4) { return BitConverter.ToInt32(result, 4 * index).ToBase62(); } if(length == 8) { return BitConverter.ToInt64(result, 8 * index).ToBase62(); } if(length == 16) { return BitConverter.ToInt64(result, 0).ToBase62() + BitConverter.ToInt64(result, 8).ToBase62(); } if(length > 16) { return BitConverter.ToInt64(result, 0).ToBase62() + BitConverter.ToInt64(result, 8).ToBase62() + length.ToBase62(); } throw (new ArgumentOutOfRangeException()); } } } }