Introduction
Sometimes you need to create words from a given alphabet, so I'd like to share a very simple solution. The solution is scalable, so you can add your own alphabet. Let's take a look at the code.
Using the Code
The code consists of several classes:
AlphabetDictionaries
- predefined alphabets AlphabetWordGenerator
- generate word accordingly alphabet
public static class AlphabetDictionaries
{
public const string EnglishLowerCase = "abcdefghijklmnopqrstuvwxyz";
public const string EnglishUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public const string Numeric = "0123456789";
public const string SpecialSymbols = "`~!@#$%^&*()-_=+[]{}\\|;:'\",<.>/?";
}
Here's main and only one class -
AlphabetWordGenerator
:
public sealed class AlphabetWordGenerator : IWordGenerator
{
private readonly string _alphabet;
private readonly RNGCryptoServiceProvider _provider = new RNGCryptoServiceProvider();
public AlphabetWordGenerator(ICollection<string> alphabets)
{
if (alphabets == null || alphabets.Count == 0)
{
throw new ArgumentException("Alphabets is null or empty");
}
if (alphabets.Any(string.IsNullOrWhiteSpace))
{
throw new ArgumentException("Alphabet should not be ampty");
}
_alphabet = string.Join(string.Empty, alphabets);
}
public AlphabetWordGenerator(string alphabet)
: this(new[] { alphabet })
{
}
public string Generate(int wordLength)
{
if (wordLength < 1)
{
throw new IndexOutOfRangeException("wordLength is out of range");
}
return DoGenerate(wordLength);
}
private string DoGenerate(int wordLength)
{
var repository = new List<char>(wordLength);
var data = new byte[wordLength];
_provider.GetBytes(data);
foreach (byte item in data)
{
int index = Convert.ToInt32(item)%_alphabet.Length;
char symbol = _alphabet[index];
repository.Add(symbol);
}
return string.Join(string.Empty, repository);
}
}
Let's create a word with lowercase English letters:
var generator = new AlphabetWordGenerator(AlphabetDictionaries.EnglishLowerCase);
var password = generator.Generate(10);
Result password is equal to uddfxjfbxp
Another example with several alphabets:
var alphabets = new List<string>
{
AlphabetDictionaries.EnglishLowerCase,
AlphabetDictionaries.EnglishUpperCase,
AlphabetDictionaries.Numeric,
AlphabetDictionaries.SpecialSymbols,
};
var generator = new AlphabetWordGenerator(alphabets);
var password = generator.Generate(40);
Result password is equal to [3xH(kzizo@51m@q}qpIYq[CgUBbjKf^3E@JF^T;
History
- 26th July, 2012: Initial version
- 20th December, 2013:
Length
's been moved to generate method