77 lines
2.3 KiB
C#
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());
|
|
}
|
|
}
|
|
}
|
|
}
|