Files
Api/DouyinApi.Services/NamingService.cs

205 lines
7.2 KiB
C#
Raw Normal View History

2025-11-05 00:22:21 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using DouyinApi.IServices;
using DouyinApi.Model.Naming;
namespace DouyinApi.Services
{
public class NamingService : INamingService
{
private static readonly Regex SurnameRegex = new(@"^[\u4e00-\u9fa5]{1,2}$", RegexOptions.Compiled);
private static readonly IReadOnlyList<char> MaleCharacters = new[]
{
'辰', '昇', '曜', '瀚', '宸', '沐', '景', '霖', '晟', '玥', '骁', '煜', '澜', '珩', '聿', '澄', '钧'
};
private static readonly IReadOnlyList<char> FemaleCharacters = new[]
{
'瑶', '霏', '婉', '绮', '璇', '芷', '乂', '灵', '沁', '语', '晴', '若', '绫', '芸', '络', '梦', '澜'
};
private static readonly IReadOnlyList<char> NeutralCharacters = new[]
{
'玄', '洛', '岚', '澈', '岑', '泓', '澜', '烨', '闻', '黎', '墨', '夙', '羲', '霆', '渊', '翎'
};
private static readonly Dictionary<char, string> CharacterMeanings = new()
{
['辰'] = "辰曜星光",
['昇'] = "旭日东升",
['曜'] = "光耀万里",
['瀚'] = "瀚海无垠",
['宸'] = "王者气度",
['沐'] = "沐浴祥瑞",
['景'] = "景行德高",
['霖'] = "甘霖润泽",
['晟'] = "光明昌盛",
['玥'] = "王者之玉",
['骁'] = "英勇不屈",
['煜'] = "照耀四方",
['澜'] = "碧波浩渺",
['珩'] = "璞玉内敛",
['聿'] = "持守正道",
['澄'] = "心境澄明",
['钧'] = "乾坤平衡",
['瑶'] = "瑶光琼华",
['霏'] = "霏霏瑞雪",
['婉'] = "柔婉清扬",
['绮'] = "绮丽灵动",
['璇'] = "璇玑回转",
['芷'] = "香草高洁",
['乂'] = "安然有序",
['灵'] = "灵秀夺目",
['沁'] = "沁心甘露",
['语'] = "言语有光",
['晴'] = "晴空暖阳",
['若'] = "若水明澈",
['绫'] = "绫罗轻盈",
['芸'] = "芸芸芳草",
['络'] = "络绎华彩",
['梦'] = "梦想成真",
['玄'] = "玄妙莫测",
['洛'] = "洛水灵韵",
['岚'] = "山岚清气",
['澈'] = "心境通透",
['岑'] = "峻岭深沉",
['泓'] = "泓泉清澈",
['烨'] = "火光通明",
['闻'] = "名闻四海",
['黎'] = "黎明曙光",
['墨'] = "墨香书韵",
['夙'] = "夙愿成真",
['羲'] = "伏羲灵息",
['霆'] = "雷霆万钧",
['渊'] = "渊源深厚",
['翎'] = "翎羽轻灵"
};
private static readonly string[] Blessings =
{
"引瑞气入怀,扶摇直上",
"承先祖之德,守家风之和",
"与四时共鸣,步步生辉",
"纳天地灵气,行稳致远",
"凝万象之精魄,护佑昌隆",
"藏锋于怀,静待时来",
"兼济天下情怀,拥抱广阔未来"
};
public Task<bool> ValidateSurnameAsync(string surname)
{
if (string.IsNullOrWhiteSpace(surname))
{
return Task.FromResult(false);
}
return Task.FromResult(SurnameRegex.IsMatch(surname.Trim()));
}
public async Task<NamingResponse> GenerateNamesAsync(NamingRequest request)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
if (!await ValidateSurnameAsync(request.Surname))
{
throw new ArgumentException("invalid_surname");
}
var seed = CreateSeed(request);
var random = new Random(seed);
var pool = request.Gender == "female" ? FemaleCharacters : MaleCharacters;
var fallbackPool = NeutralCharacters;
var suggestions = new List<NamingSuggestion>();
var attempts = 0;
while (suggestions.Count < 5 && attempts < 100)
{
attempts++;
var given = GenerateGivenName(request.NameLength, pool, fallbackPool, random);
var fullName = $"{request.Surname}{given}";
if (suggestions.Any(s => s.Name == fullName))
{
continue;
}
var meaning = ComposeMeaning(request.Surname, given, request.BirthDate, request.BirthTime, random);
suggestions.Add(new NamingSuggestion
{
Name = fullName,
Meaning = meaning
});
}
if (!suggestions.Any())
{
suggestions.Add(new NamingSuggestion
{
Name = $"{request.Surname}玄珏",
Meaning = "玄珠映月,珏石生辉,与生辰相应,寓意行稳致远"
});
}
return new NamingResponse
{
Results = suggestions
};
}
private static int CreateSeed(NamingRequest request)
{
var raw = $"{request.Surname}-{request.Gender}-{request.BirthDate}-{request.BirthTime}-{request.NameLength}";
var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(raw));
return Math.Abs(BitConverter.ToInt32(bytes, 0));
}
private static string GenerateGivenName(
string nameLength,
IReadOnlyList<char> primaryPool,
IReadOnlyList<char> fallbackPool,
Random random)
{
var buffer = new StringBuilder();
var length = nameLength == "single" ? 1 : 2;
for (var i = 0; i < length; i++)
{
var pool = (i == 0) ? primaryPool : fallbackPool;
buffer.Append(pool[random.Next(pool.Count)]);
}
return buffer.ToString();
}
private static string ComposeMeaning(string surname, string given, string birthDate, string birthTime, Random random)
{
var fragments = new List<string>();
foreach (var ch in given)
{
if (CharacterMeanings.TryGetValue(ch, out var desc))
{
fragments.Add(desc);
}
else
{
fragments.Add($"{ch}寓意祥瑞");
}
}
var blessing = Blessings[random.Next(Blessings.Length)];
var birthFragment = string.IsNullOrWhiteSpace(birthTime)
? $"{birthDate}之辰"
: $"{birthDate} {birthTime} 时刻";
return $"{string.Join("", fragments)},与{surname}氏气脉相连,于{birthFragment}呼应,{blessing}。";
}
}
}