Skip to content

Commit 2de2da4

Browse files
authored
Merge pull request #44 from SecurityCze/word_casing
Add Random Whole Word word casing option
2 parents d07f9bd + e9751fb commit 2de2da4

2 files changed

Lines changed: 44 additions & 13 deletions

File tree

Diceware.cs

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,17 +135,19 @@ private static void VerifyOptions(Options options, PwProfile profile)
135135
}
136136
}
137137

138-
private static void ApplyWordCasing(string[] words, WordCasingType wordCasing, CryptoRandomStream random)
138+
/// <summary>
139+
/// Applies word casings that can modify multiple words.
140+
/// </summary>
141+
/// <param name="words">list of words to apply word casing to.</param>
142+
/// <param name="wordCasing">requested word casing type.</param>
143+
/// <param name="random">PRNG source.</param>
144+
private static void ApplyWordCasingAcrossMultipleWords(string[] words, WordCasingType wordCasing, CryptoRandomStream random)
139145
{
140-
if (wordCasing == WordCasingType.DoNotChange)
141-
{
142-
return;
143-
}
144-
145146
for (int scan = 0; scan < words.Length; ++scan)
146147
{
147148
switch (wordCasing)
148149
{
150+
// case WordCasingType.DoNotChange: // handled in ApplyWordCasing
149151
case WordCasingType.Lowercase:
150152
words[scan] = words[scan].ToLowerInvariant();
151153
break;
@@ -156,13 +158,7 @@ private static void ApplyWordCasing(string[] words, WordCasingType wordCasing, C
156158
string first = words[scan][0].ToString().ToUpperInvariant();
157159
words[scan] = $"{first}{words[scan].Substring(1)}";
158160
break;
159-
case WordCasingType.TitleCaseFirst:
160-
if (scan == 0)
161-
{
162-
string titleFirst = words[scan][0].ToString().ToUpperInvariant();
163-
words[scan] = $"{titleFirst}{words[scan].Substring(1)}";
164-
}
165-
break;
161+
// case WordCasingType.TitleCaseFirst: // handled in ApplyWordCasing
166162
case WordCasingType.TitleCaseRandom:
167163
if (random.CoinToss())
168164
{
@@ -179,6 +175,7 @@ private static void ApplyWordCasing(string[] words, WordCasingType wordCasing, C
179175
.ToArray();
180176
words[scan] = new string(randomized);
181177
break;
178+
// case WordCasingType.WholeWordOneRandom: // handled in ApplyWordCasing
182179
case WordCasingType.WholeWord:
183180
if (random.CoinToss())
184181
{
@@ -191,6 +188,38 @@ private static void ApplyWordCasing(string[] words, WordCasingType wordCasing, C
191188
}
192189
}
193190

191+
/// <summary>
192+
/// Applies word casings.
193+
/// </summary>
194+
/// <param name="words">list of words to apply word casing to.</param>
195+
/// <param name="wordCasing">requested word casing type.</param>
196+
/// <param name="random">PRNG source.</param>
197+
private static void ApplyWordCasing(string[] words, WordCasingType wordCasing, CryptoRandomStream random)
198+
{
199+
if (words.Length == 0)
200+
{
201+
return; // No words to Word Cast
202+
}
203+
204+
// Handle single word modifications, pass the rest to ApplyWordCasingAcrossMultipleWords
205+
switch (wordCasing)
206+
{
207+
case WordCasingType.DoNotChange:
208+
break;
209+
case WordCasingType.TitleCaseFirst:
210+
string titleFirst = words[0][0].ToString().ToUpperInvariant();
211+
words[0] = $"{titleFirst}{words[0].Substring(1)}";
212+
break;
213+
case WordCasingType.WholeWordOneRandom:
214+
int randomWordIndex = random.AtMost(words.Length - 1);
215+
words[randomWordIndex] = words[randomWordIndex].ToUpperInvariant();
216+
break;
217+
default:
218+
ApplyWordCasingAcrossMultipleWords(words, wordCasing, random);
219+
break;
220+
}
221+
}
222+
194223
private static void ApplyL33tSpeak(string[] words, L33tSpeakType l33tSpeak, CryptoRandomStream random)
195224
{
196225
if (l33tSpeak == L33tSpeakType.None)

WordCasingType.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public enum WordCasingType
3333
[Description("Title Case Random")]
3434
TitleCaseRandom,
3535
Random,
36+
[Description("Random Whole Word")]
37+
WholeWordOneRandom,
3638
[Description("Random Whole Words")]
3739
WholeWord,
3840
};

0 commit comments

Comments
 (0)