我知道有几篇关于基于大词典或网页查找的随机单词生成的帖子。但是,我正在寻找一个单词生成器,我可以使用它来创建没有符号的强密码。我正在寻找的是一种可靠的机制来生成给定长度的随机,无法识别的英语单词。
单词类型的一个例子是“ratanta”等。
是否有任何算法可以理解兼容的音节,从而生成可发音的输出字符串?我知道某些验证码样式控件会生成这些类型的单词,但我不确定它们是使用算法还是来自大型集合。
如果有这种功能的任何.Net实现,我将非常有兴趣知道。
答案 0 :(得分:3)
我会使用Markov chain算法。
总结:
答案 1 :(得分:2)
你可以做几件事:
1)研究英语音节结构,并按照这些规则生成音节
2)采用马尔可夫链来获得英语音韵学的统计模型。
马尔可夫链上有很多资源,但主要思想是记录某个序列后出现任何特定字母的概率。例如,在“q”之后,“u”非常可能;在“k”之后,“q”非常不可能(这采用1长马尔可夫链);或者,在“th”之后,“e”很可能(这采用2长马尔可夫链)。
如果你去音节模型路线,你可以使用像this这样的资源来帮助你阐明你对你语言的直觉。
<强>更新强>:
3)你可以通过不模拟完整的英语来简化它,但是,比如日语或意大利语,规则更容易,如果它是一个无意义的单词,它就像一个无意义的英语单词一样容易记住。例如,日语只有大约94个有效音节(47短,47长),你可以轻松列出所有这些音节并随机选择。
答案 2 :(得分:0)
一些答案建议使用马尔可夫链,但不要告诉您如何构建。这是一个实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
namespace PseudoWord
{
public sealed class PseudoWordGenerator : IDisposable
{
private readonly RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
private readonly HashSet<string> enders = new HashSet<string>();
private readonly IList<string> starters = new List<string>();
private readonly Dictionary<char, IList<string>> gramDict =
Enumerable
.Range('a', 'z')
.ToDictionary(a => (char) a, _ => (IList<string>) new List<string>());
private readonly byte[] randomBytes = new byte[4];
public PseudoWordGenerator(IEnumerable<string> words, int gramLen)
{
foreach (var word in words.Select(w => w.Trim().ToLower()).Where(w => w.Length > gramLen)
.Where(w => Regex.IsMatch(w, "^[a-z]+$")))
{
this.starters.Add(word.Substring(0, gramLen));
this.enders.Add(word.Substring(word.Length - gramLen, gramLen));
for (var i = 0; i < word.Length - gramLen; i++)
{
var currentLetter = word[i];
if (!this.gramDict.TryGetValue(currentLetter, out var grams))
{
i = word.Length;
continue;
}
grams.Add(word.Substring(i + 1, gramLen));
}
}
}
public string BuildPseudoWord(int length)
{
var result = new StringBuilder(this.GetRandomStarter());
var lastGram = string.Empty;
while (result.Length < length || !this.enders.Contains(lastGram))
{
lastGram = this.GetRandomGram(result[result.Length - 1]);
result.Append(lastGram);
}
return result.ToString();
}
private string GetRandomStarter() => this.GetRandomElement(this.starters);
private string GetRandomGram(char preceding) =>
this.GetRandomElement(this.gramDict[preceding]);
private T GetRandomElement<T>(IList<T> collection) =>
collection[this.GetRandomUnsigned(collection.Count - 1)];
public void Dispose()
{
for (var i = 0; i < this.randomBytes.Length; i++)
{
this.randomBytes[i] = 0;
}
this.rng?.Dispose();
}
private int GetRandomUnsigned(int max)
{
this.rng.GetBytes(this.randomBytes);
return Math.Abs(BitConverter.ToInt32(this.randomBytes, 0)) % (max + 1);
}
}
}
以gramLen = 3并以"linuxwords" Linux dictionary作为输入,这是至少12个字符的示例输出
larisommento
damentivesto
honsgranspireas
incenctorsed
opemelersult
spenedriarblast
devokepocian
newmenaryrofile
perocererich
trerwhusinis
通过简单地将重复存储在数组中以处理概率,简化了此实现。此外,我们专门处理单词的开头和结尾以生成更合理的单词。