Files
qrcodeService/QRCodeService/Services/ShortCodeService.cs
2021-04-21 17:32:06 +08:00

77 lines
2.3 KiB
C#

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<string> 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;
}
}
}
/// <summary>
/// 计算短链接
/// </summary>
/// <param name="url"></param>
/// <param name="length">4(四分之一) 8(半) 16(全长)</param>
/// <param name="index"></param>
/// <returns></returns>
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());
}
}
}
}