Files
Api/DouyinApi.Services/NamingService.cs
2025-11-05 00:22:21 +08:00

205 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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}。";
}
}
}