include some more options in the password generator (extended special group, at least one from every group, exclude look-alike), closes some items of https://github.com/PhilippC/keepass2android/issues/81
This commit is contained in:
@@ -24,14 +24,43 @@ using Android.OS;
|
||||
using Android.Preferences;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar", WindowSoftInputMode = SoftInput.StateHidden, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
|
||||
public class GeneratePasswordActivity : LockCloseActivity {
|
||||
private readonly int[] _buttonIds = new[] {Resource.Id.btn_length6, Resource.Id.btn_length8, Resource.Id.btn_length12, Resource.Id.btn_length16};
|
||||
public class GeneratePasswordActivity :
|
||||
#if DEBUG
|
||||
LifecycleAwareActivity
|
||||
#else
|
||||
LockCloseActivity
|
||||
#endif
|
||||
|
||||
private ActivityDesign _design;
|
||||
{
|
||||
private readonly int[] _buttonLengthButtonIds = new[] {Resource.Id.btn_length6,
|
||||
Resource.Id.btn_length8,
|
||||
Resource.Id.btn_length12,
|
||||
Resource.Id.btn_length16,
|
||||
Resource.Id.btn_length24,
|
||||
Resource.Id.btn_length32};
|
||||
|
||||
private readonly int[] _checkboxIds = new[] {Resource.Id.cb_uppercase,
|
||||
Resource.Id.cb_lowercase,
|
||||
Resource.Id.cb_digits,
|
||||
Resource.Id.cb_minus,
|
||||
Resource.Id.cb_underline,
|
||||
Resource.Id.cb_space,
|
||||
Resource.Id.cb_specials,
|
||||
Resource.Id.cb_specials_extended,
|
||||
Resource.Id.cb_brackets,
|
||||
Resource.Id.cb_at_least_one_from_each_group,
|
||||
Resource.Id.cb_exclude_lookalike
|
||||
};
|
||||
|
||||
PasswordFont _passwordFont = new PasswordFont();
|
||||
|
||||
|
||||
private ActivityDesign _design;
|
||||
public GeneratePasswordActivity()
|
||||
{
|
||||
_design = new ActivityDesign(this);
|
||||
@@ -47,7 +76,10 @@ namespace keepass2android
|
||||
{
|
||||
Intent i = new Intent(act, typeof(GeneratePasswordActivity));
|
||||
|
||||
#if DEBUG
|
||||
#else
|
||||
i.PutExtra(NoLockCheck, true);
|
||||
#endif
|
||||
|
||||
act.StartActivityForResult(i, 0);
|
||||
}
|
||||
@@ -61,17 +93,54 @@ namespace keepass2android
|
||||
SetResult(KeePass.ExitNormal);
|
||||
|
||||
var prefs = GetPreferences(FileCreationMode.Private);
|
||||
((CheckBox) FindViewById(Resource.Id.cb_uppercase)).Checked = prefs.GetBoolean("cb_uppercase", true);
|
||||
((CheckBox)FindViewById(Resource.Id.cb_lowercase)).Checked = prefs.GetBoolean("cb_lowercase", true);
|
||||
((CheckBox)FindViewById(Resource.Id.cb_digits)).Checked = prefs.GetBoolean("cb_digits", true);
|
||||
((CheckBox)FindViewById(Resource.Id.cb_minus)).Checked = prefs.GetBoolean("cb_minus", false);
|
||||
((CheckBox)FindViewById(Resource.Id.cb_underline)).Checked = prefs.GetBoolean("cb_underline", false);
|
||||
((CheckBox)FindViewById(Resource.Id.cb_space)).Checked = prefs.GetBoolean("cb_space", false);
|
||||
((CheckBox)FindViewById(Resource.Id.cb_specials)).Checked = prefs.GetBoolean("cb_specials", false);
|
||||
((CheckBox)FindViewById(Resource.Id.cb_brackets)).Checked = prefs.GetBoolean("cb_brackets", false);
|
||||
((EditText)FindViewById(Resource.Id.length)).Text = prefs.GetInt("length", 12).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
|
||||
PasswordGenerator.PasswordGenerationOptions options = null;
|
||||
string jsonOptions = prefs.GetString("password_generator_options", null);
|
||||
if (jsonOptions != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
options = JsonConvert.DeserializeObject<PasswordGenerator.PasswordGenerationOptions>(jsonOptions);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
options = new PasswordGenerator.PasswordGenerationOptions()
|
||||
{
|
||||
Length = prefs.GetInt("length", 12),
|
||||
UpperCase = prefs.GetBoolean("cb_uppercase", true),
|
||||
LowerCase = prefs.GetBoolean("cb_lowercase", true),
|
||||
Digits = prefs.GetBoolean("cb_digits", true),
|
||||
Minus = prefs.GetBoolean("cb_minus", false),
|
||||
Underline = prefs.GetBoolean("cb_underline", false),
|
||||
Space = prefs.GetBoolean("cb_space", false),
|
||||
Specials = prefs.GetBoolean("cb_specials", false),
|
||||
SpecialsExtended = false,
|
||||
Brackets = prefs.GetBoolean("cb_brackets", false)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
((CheckBox)FindViewById(Resource.Id.cb_uppercase)).Checked = options.UpperCase;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_lowercase)).Checked = options.LowerCase;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_digits)).Checked = options.Digits;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_minus)).Checked = options.Minus;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_underline)).Checked = options.Underline;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_space)).Checked = options.Space;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_specials)).Checked = options.Specials;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_specials_extended)).Checked = options.SpecialsExtended;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_brackets)).Checked = options.Brackets;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_exclude_lookalike)).Checked = options.ExcludeLookAlike;
|
||||
((CheckBox)FindViewById(Resource.Id.cb_at_least_one_from_each_group)).Checked = options.AtLeastOneFromEachGroup;
|
||||
|
||||
((EditText)FindViewById(Resource.Id.length)).Text = options.Length.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
foreach (int id in _buttonIds) {
|
||||
foreach (int id in _buttonLengthButtonIds) {
|
||||
Button button = (Button) FindViewById(id);
|
||||
button.Click += (sender, e) =>
|
||||
{
|
||||
@@ -79,17 +148,18 @@ namespace keepass2android
|
||||
|
||||
EditText editText = (EditText) FindViewById(Resource.Id.length);
|
||||
editText.Text = b.Text;
|
||||
UpdatePassword();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
Button genPassButton = (Button) FindViewById(Resource.Id.generate_password_button);
|
||||
genPassButton.Click += (sender, e) => {
|
||||
String password = GeneratePassword();
|
||||
|
||||
EditText txtPassword = (EditText) FindViewById(Resource.Id.password_edit);
|
||||
txtPassword.Text = password;
|
||||
};
|
||||
|
||||
foreach (int id in _checkboxIds)
|
||||
{
|
||||
FindViewById<CheckBox>(id).CheckedChange += (sender, args) => UpdatePassword();
|
||||
}
|
||||
|
||||
Button genPassButton = (Button) FindViewById(Resource.Id.generate_password_button);
|
||||
genPassButton.Click += (sender, e) => { UpdatePassword(); };
|
||||
|
||||
|
||||
|
||||
@@ -118,12 +188,22 @@ namespace keepass2android
|
||||
EditText txtPasswordToSet = (EditText) FindViewById(Resource.Id.password_edit);
|
||||
txtPasswordToSet.Text = GeneratePassword();
|
||||
|
||||
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||
_passwordFont.ApplyTo(txtPasswordToSet);
|
||||
|
||||
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||
SupportActionBar.SetHomeButtonEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
public String GeneratePassword() {
|
||||
|
||||
private void UpdatePassword()
|
||||
{
|
||||
String password = GeneratePassword();
|
||||
|
||||
EditText txtPassword = (EditText) FindViewById(Resource.Id.password_edit);
|
||||
txtPassword.Text = password;
|
||||
}
|
||||
|
||||
public String GeneratePassword() {
|
||||
String password = "";
|
||||
|
||||
try {
|
||||
@@ -137,29 +217,15 @@ namespace keepass2android
|
||||
|
||||
|
||||
PasswordGenerator generator = new PasswordGenerator(this);
|
||||
|
||||
password = generator.GeneratePassword(length,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_uppercase)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_lowercase)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_digits)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_minus)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_underline)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_space)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_specials)).Checked,
|
||||
((CheckBox) FindViewById(Resource.Id.cb_brackets)).Checked);
|
||||
|
||||
var options = GetOptions(length);
|
||||
|
||||
password = generator.GeneratePassword(options);
|
||||
|
||||
var prefs = GetPreferences(FileCreationMode.Private);
|
||||
prefs.Edit()
|
||||
.PutBoolean("cb_uppercase", ((CheckBox) FindViewById(Resource.Id.cb_uppercase)).Checked)
|
||||
.PutBoolean("cb_lowercase", ((CheckBox) FindViewById(Resource.Id.cb_lowercase)).Checked)
|
||||
.PutBoolean("cb_digits", ((CheckBox) FindViewById(Resource.Id.cb_digits)).Checked)
|
||||
.PutBoolean("cb_minus", ((CheckBox) FindViewById(Resource.Id.cb_minus)).Checked)
|
||||
.PutBoolean("cb_underline", ((CheckBox) FindViewById(Resource.Id.cb_underline)).Checked)
|
||||
.PutBoolean("cb_space", ((CheckBox) FindViewById(Resource.Id.cb_space)).Checked)
|
||||
.PutBoolean("cb_specials", ((CheckBox) FindViewById(Resource.Id.cb_specials)).Checked)
|
||||
.PutBoolean("cb_brackets", ((CheckBox) FindViewById(Resource.Id.cb_brackets)).Checked)
|
||||
.PutInt("length", length)
|
||||
.Commit();
|
||||
.PutString("password_generator_options", JsonConvert.SerializeObject(options))
|
||||
.Commit();
|
||||
|
||||
|
||||
|
||||
@@ -170,6 +236,26 @@ namespace keepass2android
|
||||
return password;
|
||||
}
|
||||
|
||||
private PasswordGenerator.PasswordGenerationOptions GetOptions(int length)
|
||||
{
|
||||
PasswordGenerator.PasswordGenerationOptions options = new PasswordGenerator.PasswordGenerationOptions()
|
||||
{
|
||||
Length = length,
|
||||
UpperCase = ((CheckBox) FindViewById(Resource.Id.cb_uppercase)).Checked,
|
||||
LowerCase = ((CheckBox) FindViewById(Resource.Id.cb_lowercase)).Checked,
|
||||
Digits = ((CheckBox) FindViewById(Resource.Id.cb_digits)).Checked,
|
||||
Minus = ((CheckBox) FindViewById(Resource.Id.cb_minus)).Checked,
|
||||
Underline = ((CheckBox) FindViewById(Resource.Id.cb_underline)).Checked,
|
||||
Space = ((CheckBox) FindViewById(Resource.Id.cb_space)).Checked,
|
||||
Specials = ((CheckBox) FindViewById(Resource.Id.cb_specials)).Checked,
|
||||
SpecialsExtended = ((CheckBox) FindViewById(Resource.Id.cb_specials_extended)).Checked,
|
||||
Brackets = ((CheckBox) FindViewById(Resource.Id.cb_brackets)).Checked,
|
||||
ExcludeLookAlike = ((CheckBox) FindViewById(Resource.Id.cb_exclude_lookalike)).Checked,
|
||||
AtLeastOneFromEachGroup = ((CheckBox) FindViewById(Resource.Id.cb_at_least_one_from_each_group)).Checked
|
||||
};
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
public override bool OnOptionsItemSelected(IMenuItem item)
|
||||
{
|
||||
@@ -181,7 +267,7 @@ namespace keepass2android
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -65,39 +65,53 @@ android:background="?activityBackgroundColor"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_below="@id/generate_password_button" />
|
||||
<Button
|
||||
android:id="@+id/btn_length16"
|
||||
android:text="16"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_width="60sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/length_label" />
|
||||
android:id="@+id/btn_length32"
|
||||
android:text="32"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_width="50sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/length_label" />
|
||||
<Button
|
||||
android:id="@+id/btn_length24"
|
||||
android:text="24"
|
||||
android:layout_toLeftOf="@id/btn_length32"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="50sp"
|
||||
android:layout_alignTop="@id/btn_length32" />
|
||||
<Button
|
||||
android:id="@+id/btn_length16"
|
||||
android:text="16"
|
||||
android:layout_toLeftOf="@id/btn_length24"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="50sp"
|
||||
android:layout_alignTop="@id/btn_length32" />
|
||||
<Button
|
||||
android:id="@+id/btn_length12"
|
||||
android:text="12"
|
||||
android:layout_toLeftOf="@id/btn_length16"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="60sp"
|
||||
android:layout_alignTop="@id/btn_length16" />
|
||||
android:layout_width="50sp"
|
||||
android:layout_alignTop="@id/btn_length32" />
|
||||
<Button
|
||||
android:id="@+id/btn_length8"
|
||||
android:text="8"
|
||||
android:layout_toLeftOf="@id/btn_length12"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="60sp"
|
||||
android:layout_alignTop="@id/btn_length16" />
|
||||
android:layout_width="50sp"
|
||||
android:layout_alignTop="@id/btn_length32" />
|
||||
<Button
|
||||
android:id="@+id/btn_length6"
|
||||
android:text="6"
|
||||
android:layout_toLeftOf="@id/btn_length8"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="60sp"
|
||||
android:layout_alignTop="@id/btn_length16" />
|
||||
android:layout_width="50sp"
|
||||
android:layout_alignTop="@id/btn_length32" />
|
||||
<EditText
|
||||
android:id="@+id/length"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_toLeftOf="@id/btn_length6"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/btn_length16"
|
||||
android:layout_alignTop="@id/btn_length32"
|
||||
android:singleLine="true"
|
||||
android:text="12"
|
||||
android:hint="@string/hint_length" />
|
||||
@@ -146,12 +160,31 @@ android:background="?activityBackgroundColor"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/special"
|
||||
android:layout_below="@id/cb_space" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cb_specials_extended"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/special_extended"
|
||||
android:layout_below="@id/cb_specials" />
|
||||
<CheckBox
|
||||
android:id="@+id/cb_brackets"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/brackets"
|
||||
android:layout_below="@id/cb_specials" />
|
||||
android:layout_below="@id/cb_specials_extended" />
|
||||
<CheckBox
|
||||
android:id="@+id/cb_exclude_lookalike"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/exclude_lookalike"
|
||||
android:layout_below="@id/cb_brackets" />
|
||||
<CheckBox
|
||||
android:id="@+id/cb_at_least_one_from_each_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/at_least_one_from_each_group"
|
||||
android:layout_below="@id/cb_exclude_lookalike" />
|
||||
</RelativeLayout>
|
||||
</ScrollView>
|
||||
</RelativeLayout>
|
||||
@@ -263,6 +263,9 @@
|
||||
|
||||
|
||||
<string name="special">Special</string>
|
||||
<string name="special_extended">Extended Special</string>
|
||||
<string name="at_least_one_from_each_group">At least one from each group</string>
|
||||
<string name="exclude_lookalike">Exclude look-alike characters</string>
|
||||
<string name="search_hint">Find what</string>
|
||||
<string name="search_results">Search results</string>
|
||||
<string name="search_in">Search in</string>
|
||||
|
||||
@@ -16,6 +16,8 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Android.Content;
|
||||
@@ -33,6 +35,7 @@ namespace keepass2android
|
||||
private const String UnderlineChars = "_";
|
||||
private const String SpaceChars = " ";
|
||||
private const String SpecialChars = "!\"#$%&'*+,./:;=?@\\^`";
|
||||
private const String ExtendedChars = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||||
private const String BracketChars = "[]{}()<>";
|
||||
|
||||
private readonly Context _cxt;
|
||||
@@ -47,7 +50,7 @@ namespace keepass2android
|
||||
{
|
||||
var data = new byte[sizeof(int)];
|
||||
_rng.GetBytes(data);
|
||||
return BitConverter.ToInt32(data, 0) & (int.MaxValue - 1);
|
||||
return BitConverter.ToInt32(data, 0) & (Int32.MaxValue - 1);
|
||||
}
|
||||
|
||||
public override int Next(int maxValue)
|
||||
@@ -69,7 +72,7 @@ namespace keepass2android
|
||||
var data = new byte[sizeof(uint)];
|
||||
_rng.GetBytes(data);
|
||||
var randUint = BitConverter.ToUInt32(data, 0);
|
||||
return randUint / (uint.MaxValue + 1.0);
|
||||
return randUint / (UInt32.MaxValue + 1.0);
|
||||
}
|
||||
|
||||
public override void NextBytes(byte[] data)
|
||||
@@ -81,64 +84,136 @@ namespace keepass2android
|
||||
public PasswordGenerator(Context cxt) {
|
||||
_cxt = cxt;
|
||||
}
|
||||
|
||||
public String GeneratePassword(int length, bool upperCase, bool lowerCase, bool digits, bool minus, bool underline, bool space, bool specials, bool brackets) {
|
||||
if (length <= 0)
|
||||
|
||||
|
||||
public class PasswordGenerationOptions
|
||||
{
|
||||
public int Length { get; set; }
|
||||
public bool UpperCase { get; set; }
|
||||
public bool LowerCase { get; set; }
|
||||
public bool Digits { get; set; }
|
||||
public bool Minus { get; set; }
|
||||
public bool Underline { get; set; }
|
||||
public bool Space { get; set; }
|
||||
public bool Specials { get; set; }
|
||||
public bool SpecialsExtended { get; set; }
|
||||
public bool Brackets { get; set; }
|
||||
|
||||
public bool ExcludeLookAlike { get; set; }
|
||||
public bool AtLeastOneFromEachGroup { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public String GeneratePassword(PasswordGenerationOptions options) {
|
||||
if (options.Length <= 0)
|
||||
throw new ArgumentException(_cxt.GetString(Resource.String.error_wrong_length));
|
||||
|
||||
if (!upperCase && !lowerCase && !digits && !minus && !underline && !space && !specials && !brackets)
|
||||
throw new ArgumentException(_cxt.GetString(Resource.String.error_pass_gen_type));
|
||||
|
||||
String characterSet = GetCharacterSet(upperCase, lowerCase, digits, minus, underline, space, specials, brackets);
|
||||
|
||||
|
||||
|
||||
var groups = GetCharacterGroups(options);
|
||||
String characterSet = GetCharacterSet(options, groups);
|
||||
|
||||
if (characterSet.Length == 0)
|
||||
throw new ArgumentException(_cxt.GetString(Resource.String.error_pass_gen_type));
|
||||
|
||||
int size = characterSet.Length;
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
Random random = new SecureRandom();
|
||||
|
||||
if (options.AtLeastOneFromEachGroup)
|
||||
{
|
||||
foreach (var g in groups)
|
||||
{
|
||||
if (g.Length > 0)
|
||||
{
|
||||
buffer.Append(g[random.Next(g.Length)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
while (buffer.Length < options.Length)
|
||||
{
|
||||
char c = characterSet[random.Next(size)];
|
||||
|
||||
buffer.Append(c);
|
||||
buffer.Append(characterSet[random.Next(size)]);
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.ToString();
|
||||
}
|
||||
|
||||
public String GetCharacterSet(bool upperCase, bool lowerCase, bool digits, bool minus, bool underline, bool space, bool specials, bool brackets) {
|
||||
StringBuilder charSet = new StringBuilder();
|
||||
|
||||
if (upperCase)
|
||||
charSet.Append(UpperCaseChars);
|
||||
|
||||
if (lowerCase)
|
||||
charSet.Append(LowerCaseChars);
|
||||
|
||||
if (digits)
|
||||
charSet.Append(DigitChars);
|
||||
|
||||
if (minus)
|
||||
charSet.Append(MinusChars);
|
||||
|
||||
if (underline)
|
||||
charSet.Append(UnderlineChars);
|
||||
|
||||
if (space)
|
||||
charSet.Append(SpaceChars);
|
||||
|
||||
if (specials)
|
||||
charSet.Append(SpecialChars);
|
||||
|
||||
if (brackets)
|
||||
charSet.Append(BracketChars);
|
||||
|
||||
return charSet.ToString();
|
||||
}
|
||||
}
|
||||
var password = buffer.ToString();
|
||||
|
||||
if (options.AtLeastOneFromEachGroup)
|
||||
{
|
||||
//shuffle
|
||||
StringBuilder sb = new StringBuilder(password);
|
||||
for (int i = (password.Length - 1); i >= 1; i--)
|
||||
{
|
||||
int j = random.Next(i + 1);
|
||||
|
||||
var tmp = sb[i];
|
||||
sb[i] = sb[j];
|
||||
sb[j] = tmp;
|
||||
}
|
||||
|
||||
password = sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
public string GetCharacterSet(PasswordGenerationOptions options, List<string> groups)
|
||||
{
|
||||
var characterSet = String.Join("", groups);
|
||||
|
||||
return characterSet;
|
||||
|
||||
}
|
||||
|
||||
private static List<string> GetCharacterGroups(PasswordGenerationOptions options)
|
||||
{
|
||||
List<string> groups = new List<string>();
|
||||
|
||||
if (options.UpperCase)
|
||||
groups.Add(UpperCaseChars);
|
||||
|
||||
if (options.LowerCase)
|
||||
groups.Add(LowerCaseChars);
|
||||
|
||||
if (options.Digits)
|
||||
groups.Add(DigitChars);
|
||||
|
||||
if (options.Minus)
|
||||
groups.Add(MinusChars);
|
||||
|
||||
if (options.Underline)
|
||||
groups.Add(UnderlineChars);
|
||||
|
||||
if (options.Space)
|
||||
groups.Add(SpaceChars);
|
||||
|
||||
if (options.Specials)
|
||||
groups.Add(SpecialChars);
|
||||
|
||||
if (options.SpecialsExtended)
|
||||
groups.Add(ExtendedChars);
|
||||
|
||||
if (options.Brackets)
|
||||
groups.Add(BracketChars);
|
||||
|
||||
|
||||
if (options.ExcludeLookAlike)
|
||||
{
|
||||
for (int i = 0; i < groups.Count; i++)
|
||||
{
|
||||
groups[i] = String.Join("", groups[i].Except("Il1|8B6GO0"));
|
||||
}
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user