Skip to content

Commit 8347243

Browse files
committed
Add pass/word(code) generation util.
1 parent d84bf65 commit 8347243

2 files changed

Lines changed: 250 additions & 0 deletions

File tree

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// ***********************************************************************
2+
// Assembly : RzR.Shared.Extensions.DomainCommonExtensions
3+
// Author : RzR
4+
// Created On : 2025-02-16 19:03
5+
//
6+
// Last Modified By : RzR
7+
// Last Modified On : 2025-02-19 18:23
8+
// ***********************************************************************
9+
// <copyright file="RandomHelper.cs" company="RzR SOFT & TECH">
10+
// Copyright © RzR. All rights reserved.
11+
// </copyright>
12+
//
13+
// <summary>
14+
// </summary>
15+
// ***********************************************************************
16+
17+
#region U S A G E S
18+
19+
using System;
20+
using System.Threading;
21+
22+
#endregion
23+
24+
namespace DomainCommonExtensions.Helpers
25+
{
26+
/// -------------------------------------------------------------------------------------------------
27+
/// <summary>
28+
/// A random helper.
29+
/// </summary>
30+
/// =================================================================================================
31+
public class RandomHelper
32+
{
33+
/// -------------------------------------------------------------------------------------------------
34+
/// <summary>
35+
/// (Immutable) the locker.
36+
/// </summary>
37+
/// =================================================================================================
38+
private static readonly Lazy<object> Locker = new Lazy<object>(() => new object(), LazyThreadSafetyMode.ExecutionAndPublication);
39+
40+
/// -------------------------------------------------------------------------------------------------
41+
/// <summary>
42+
/// (Immutable) the local seed.
43+
/// </summary>
44+
/// =================================================================================================
45+
private readonly Random _localSeed;
46+
47+
/// -------------------------------------------------------------------------------------------------
48+
/// <summary>
49+
/// (Immutable) the seed.
50+
/// </summary>
51+
/// =================================================================================================
52+
private readonly Random _seed = new Random();
53+
54+
/// -------------------------------------------------------------------------------------------------
55+
/// <summary>
56+
/// Initializes a new instance of the <see cref="RandomHelper" /> class.
57+
/// </summary>
58+
/// =================================================================================================
59+
private RandomHelper() => _localSeed = _seed ?? new Random();
60+
61+
/// -------------------------------------------------------------------------------------------------
62+
/// <summary>
63+
/// Initializes a new instance of the <see cref="RandomHelper" /> class.
64+
/// </summary>
65+
/// <param name="localSeed">Random seed.</param>
66+
/// =================================================================================================
67+
public RandomHelper(Random localSeed) => _localSeed = localSeed;
68+
69+
/// -------------------------------------------------------------------------------------------------
70+
/// <summary>
71+
/// Random instance.
72+
/// </summary>
73+
/// <value>
74+
/// The instance.
75+
/// </value>
76+
/// =================================================================================================
77+
public static RandomHelper Instance { get; } = new RandomHelper();
78+
79+
/// -------------------------------------------------------------------------------------------------
80+
/// <summary>
81+
/// Generate new random number.
82+
/// </summary>
83+
/// <param name="min">(Optional) Optional. The default value is 0 (inclusive).</param>
84+
/// <param name="max">(Optional) Optional. The default value is 1 (inclusive).</param>
85+
/// <returns>
86+
/// An int.
87+
/// </returns>
88+
/// =================================================================================================
89+
public int Number(int min = 0, int max = 1)
90+
{
91+
lock (Locker.Value)
92+
{
93+
if (max < int.MaxValue) return _localSeed.Next(min, max + 1);
94+
if (min > int.MinValue) return 1 + _localSeed.Next(min - 1, max);
95+
96+
var num = _localSeed.Next();
97+
var num2 = _localSeed.Next();
98+
var num3 = (num >> 8) & 0xFFFF;
99+
var num4 = (num2 >> 8) & 0xFFFF;
100+
101+
return (num3 << 16) | num4;
102+
}
103+
}
104+
}
105+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// ***********************************************************************
2+
// Assembly : RzR.Shared.Extensions.DomainCommonExtensions
3+
// Author : RzR
4+
// Created On : 2025-02-15 13:31
5+
//
6+
// Last Modified By : RzR
7+
// Last Modified On : 2025-02-17 21:13
8+
// ***********************************************************************
9+
// <copyright file="PasswordGenerateUtils.cs" company="RzR SOFT & TECH">
10+
// Copyright © RzR. All rights reserved.
11+
// </copyright>
12+
//
13+
// <summary>
14+
// </summary>
15+
// ***********************************************************************
16+
17+
#region U S A G E S
18+
19+
using System.Collections.Generic;
20+
using System.Linq;
21+
using DomainCommonExtensions.ArraysExtensions;
22+
using DomainCommonExtensions.CommonExtensions.TypeParam;
23+
using DomainCommonExtensions.DataTypeExtensions;
24+
using DomainCommonExtensions.Helpers;
25+
26+
#endregion
27+
28+
namespace DomainCommonExtensions.Utilities
29+
{
30+
/// -------------------------------------------------------------------------------------------------
31+
/// <summary>
32+
/// A password generate utilities.
33+
/// </summary>
34+
/// =================================================================================================
35+
public static class PasswordGenerateUtils
36+
{
37+
/// -------------------------------------------------------------------------------------------------
38+
/// <summary>
39+
/// (Immutable) array of alphabets.
40+
/// </summary>
41+
/// =================================================================================================
42+
private static readonly string[] AlphabetArray =
43+
{
44+
"ABCDEFGHJKLMNOPQRSTUVWXYZ",
45+
"abcdefghijkmnopqrstuvwxyz",
46+
"0123456789",
47+
"&!#@$_?-"
48+
};
49+
50+
/// -------------------------------------------------------------------------------------------------
51+
/// <summary>
52+
/// Generates password by specified options.
53+
/// </summary>
54+
/// <param name="requiredMinimumLength">(Optional) Length of the required minimum.</param>
55+
/// <param name="requiredUniqueChar">(Optional) The required unique character.</param>
56+
/// <param name="requiredDigits">(Optional) True to required digits.</param>
57+
/// <param name="requiredLowerChars">(Optional) True to required lower characters.</param>
58+
/// <param name="requiredUpperChars">(Optional) True to required upper characters.</param>
59+
/// <param name="requiredNonAlphanumeric">(Optional) True to required non alphanumeric.</param>
60+
/// <param name="ownNonAlphanumericChars">(Optional) The own non alphanumeric characters.</param>
61+
/// <returns>
62+
/// A generated password/pass code.
63+
/// </returns>
64+
/// =================================================================================================
65+
public static string Generate(int requiredMinimumLength = 8, int requiredUniqueChar = 4, bool requiredDigits = true,
66+
bool requiredLowerChars = true, bool requiredUpperChars = true, bool requiredNonAlphanumeric = true, string[] ownNonAlphanumericChars = null
67+
)
68+
{
69+
var passCodeLength = ValidatePassCodeLength(requiredMinimumLength, requiredUniqueChar, requiredDigits,
70+
requiredLowerChars, requiredUpperChars, requiredNonAlphanumeric);
71+
72+
if (ownNonAlphanumericChars.IsNullOrEmptyEnumerable().IsFalse())
73+
{
74+
var newNonAlphaNum = AlphabetArray[3].ToStringArray().AppendIfNotExists(ownNonAlphanumericChars);
75+
AlphabetArray[3] = newNonAlphaNum.ArrayToString();
76+
}
77+
78+
var resultChars = new List<char>();
79+
var allowedPool = new[] { 0, 1, 2, 3 };
80+
var rnd = RandomHelper.Instance;
81+
82+
if (requiredUpperChars.IsTrue())
83+
resultChars.Insert(rnd.Number(0, resultChars.Count), AlphabetArray[0][rnd.Number(0, AlphabetArray[0].Length - 1)]);
84+
else allowedPool = allowedPool.RemoveItem(0);
85+
86+
if (requiredLowerChars.IsTrue())
87+
resultChars.Insert(rnd.Number(0, resultChars.Count), AlphabetArray[1][rnd.Number(0, AlphabetArray[1].Length - 1)]);
88+
else allowedPool = allowedPool.RemoveItem(1);
89+
90+
if (requiredDigits.IsTrue())
91+
resultChars.Insert(rnd.Number(0, resultChars.Count), AlphabetArray[2][rnd.Number(0, AlphabetArray[2].Length - 1)]);
92+
else allowedPool = allowedPool.RemoveItem(2);
93+
94+
if (requiredNonAlphanumeric.IsTrue())
95+
resultChars.Insert(rnd.Number(0, resultChars.Count), AlphabetArray[3][rnd.Number(0, AlphabetArray[3].Length - 1)]);
96+
else allowedPool = allowedPool.RemoveItem(3);
97+
98+
for (var i = resultChars.Count;
99+
i < passCodeLength || resultChars.Distinct().Count() < requiredUniqueChar;
100+
i++)
101+
{
102+
if (resultChars.Distinct().Count() < requiredUniqueChar && resultChars.Count == passCodeLength)
103+
{
104+
resultChars.GetDuplicates()
105+
.ForEachAndReturn(x =>
106+
{
107+
resultChars.Remove(x);
108+
i--;
109+
});
110+
}
111+
112+
var rndAlphabetIdx = allowedPool[rnd.Number(0, allowedPool.Length - 1)];
113+
var resource = AlphabetArray[rndAlphabetIdx];
114+
var rndIdx = rnd.Number(0, resultChars.Count - 1);
115+
var rndValue = resource[rnd.Number(0, resource.Length - 1)];
116+
resultChars.Insert(rndIdx, rndValue);
117+
}
118+
119+
return new string(resultChars.ToArray());
120+
}
121+
122+
/// -------------------------------------------------------------------------------------------------
123+
/// <summary>
124+
/// Validates the pass code length.
125+
/// </summary>
126+
/// <param name="requiredMinimumLength">Length of the required minimum.</param>
127+
/// <param name="requiredUniqueChar">The required unique character.</param>
128+
/// <param name="requiredDigits">True to required digits.</param>
129+
/// <param name="requiredLowerChars">True to required lower characters.</param>
130+
/// <param name="requiredUpperChars">True to required upper characters.</param>
131+
/// <param name="requiredNonAlphanumeric">True to required non alphanumeric.</param>
132+
/// <returns>
133+
/// An int.
134+
/// </returns>
135+
/// =================================================================================================
136+
private static int ValidatePassCodeLength(int requiredMinimumLength, int requiredUniqueChar, bool requiredDigits,
137+
bool requiredLowerChars, bool requiredUpperChars, bool requiredNonAlphanumeric)
138+
{
139+
var passCodeLength = requiredMinimumLength.IfFuncIsTrue(requiredUniqueChar, () => requiredMinimumLength < requiredUniqueChar);
140+
passCodeLength = passCodeLength.IfFuncIsTrue(4, () => requiredMinimumLength < 4);
141+
142+
return passCodeLength;
143+
}
144+
}
145+
}

0 commit comments

Comments
 (0)