mirror of
https://github.com/bitwarden/android.git
synced 2024-11-02 16:14:00 +03:00
169 lines
5.4 KiB
C#
169 lines
5.4 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using Bit.App.Abstractions;
|
|||
|
using Plugin.Settings.Abstractions;
|
|||
|
|
|||
|
namespace Bit.App.Services
|
|||
|
{
|
|||
|
public class PasswordGenerationService : IPasswordGenerationService
|
|||
|
{
|
|||
|
private readonly ISettings _settings;
|
|||
|
private Random _random = new Random();
|
|||
|
|
|||
|
public PasswordGenerationService(ISettings settings)
|
|||
|
{
|
|||
|
_settings = settings;
|
|||
|
}
|
|||
|
|
|||
|
public string GeneratePassword()
|
|||
|
{
|
|||
|
int minUppercase = 1,
|
|||
|
minLowercase = 1,
|
|||
|
minNumbers = _settings.GetValueOrDefault(Constants.PasswordGeneratorMinNumbers, 1),
|
|||
|
minSpecial = _settings.GetValueOrDefault(Constants.PasswordGeneratorMinSpecial, 1),
|
|||
|
length = _settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10);
|
|||
|
|
|||
|
bool uppercase = _settings.GetValueOrDefault(Constants.PasswordGeneratorUppercase, true),
|
|||
|
lowercase = _settings.GetValueOrDefault(Constants.PasswordGeneratorLowercase, true),
|
|||
|
numbers = _settings.GetValueOrDefault(Constants.PasswordGeneratorNumbers, true),
|
|||
|
special = _settings.GetValueOrDefault(Constants.PasswordGeneratorSpecial, true),
|
|||
|
ambiguous = _settings.GetValueOrDefault(Constants.PasswordGeneratorAmbiguous, false);
|
|||
|
|
|||
|
// Sanitize
|
|||
|
if(uppercase && minUppercase < 0)
|
|||
|
{
|
|||
|
minUppercase = 1;
|
|||
|
}
|
|||
|
if(lowercase && minLowercase < 0)
|
|||
|
{
|
|||
|
minLowercase = 1;
|
|||
|
}
|
|||
|
if(numbers && minNumbers < 0)
|
|||
|
{
|
|||
|
minNumbers = 1;
|
|||
|
}
|
|||
|
if(special && minSpecial < 0)
|
|||
|
{
|
|||
|
minSpecial = 1;
|
|||
|
}
|
|||
|
|
|||
|
if(length < 1)
|
|||
|
{
|
|||
|
length = 10;
|
|||
|
}
|
|||
|
var minLength = minUppercase + minLowercase + minNumbers + minSpecial;
|
|||
|
if(length < minLength)
|
|||
|
{
|
|||
|
length = minLength;
|
|||
|
}
|
|||
|
|
|||
|
var positionsBuilder = new StringBuilder();
|
|||
|
if(lowercase && minLowercase > 0)
|
|||
|
{
|
|||
|
for(int i = 0; i < minLowercase; i++)
|
|||
|
{
|
|||
|
positionsBuilder.Append("l");
|
|||
|
}
|
|||
|
}
|
|||
|
if(uppercase && minUppercase > 0)
|
|||
|
{
|
|||
|
for(int i = 0; i < minUppercase; i++)
|
|||
|
{
|
|||
|
positionsBuilder.Append("u");
|
|||
|
}
|
|||
|
}
|
|||
|
if(numbers && minNumbers > 0)
|
|||
|
{
|
|||
|
for(int i = 0; i < minNumbers; i++)
|
|||
|
{
|
|||
|
positionsBuilder.Append("n");
|
|||
|
}
|
|||
|
}
|
|||
|
if(special && minSpecial > 0)
|
|||
|
{
|
|||
|
for(int i = 0; i < minSpecial; i++)
|
|||
|
{
|
|||
|
positionsBuilder.Append("s");
|
|||
|
}
|
|||
|
}
|
|||
|
while(positionsBuilder.Length < length)
|
|||
|
{
|
|||
|
positionsBuilder.Append("a");
|
|||
|
}
|
|||
|
|
|||
|
// Shuffle
|
|||
|
var positions = positionsBuilder.ToString().ToCharArray().OrderBy(a => _random.Next()).ToArray();
|
|||
|
|
|||
|
// Build out other character sets
|
|||
|
var allCharSet = string.Empty;
|
|||
|
|
|||
|
var lowercaseCharSet = "abcdefghijkmnopqrstuvwxyz";
|
|||
|
if(ambiguous)
|
|||
|
{
|
|||
|
lowercaseCharSet = string.Concat(lowercaseCharSet, "l");
|
|||
|
}
|
|||
|
if(lowercase)
|
|||
|
{
|
|||
|
allCharSet = string.Concat(allCharSet, lowercaseCharSet);
|
|||
|
}
|
|||
|
|
|||
|
var uppercaseCharSet = "ABCDEFGHIJKLMNPQRSTUVWXYZ";
|
|||
|
if(ambiguous)
|
|||
|
{
|
|||
|
uppercaseCharSet = string.Concat(uppercaseCharSet, "O");
|
|||
|
}
|
|||
|
if(uppercase)
|
|||
|
{
|
|||
|
allCharSet = string.Concat(allCharSet, uppercaseCharSet);
|
|||
|
}
|
|||
|
|
|||
|
var numberCharSet = "23456789";
|
|||
|
if(ambiguous)
|
|||
|
{
|
|||
|
numberCharSet = string.Concat(numberCharSet, "01");
|
|||
|
}
|
|||
|
if(numbers)
|
|||
|
{
|
|||
|
allCharSet = string.Concat(allCharSet, numberCharSet);
|
|||
|
}
|
|||
|
|
|||
|
var specialCharSet = "!@#$%^&*";
|
|||
|
if(special)
|
|||
|
{
|
|||
|
allCharSet = string.Concat(allCharSet, specialCharSet);
|
|||
|
}
|
|||
|
|
|||
|
var password = new StringBuilder();
|
|||
|
for(var i = 0; i < length; i++)
|
|||
|
{
|
|||
|
string positionChars = string.Empty;
|
|||
|
switch(positions[i])
|
|||
|
{
|
|||
|
case 'l':
|
|||
|
positionChars = lowercaseCharSet;
|
|||
|
break;
|
|||
|
case 'u':
|
|||
|
positionChars = uppercaseCharSet;
|
|||
|
break;
|
|||
|
case 'n':
|
|||
|
positionChars = numberCharSet;
|
|||
|
break;
|
|||
|
case 's':
|
|||
|
positionChars = specialCharSet;
|
|||
|
break;
|
|||
|
case 'a':
|
|||
|
positionChars = allCharSet;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
var randomCharIndex = _random.Next(0, positionChars.Length - 1);
|
|||
|
password.Append(positionChars[randomCharIndex]);
|
|||
|
}
|
|||
|
|
|||
|
return password.ToString();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|