forked from kherel/selfprivacy.org.app
change password generator
parent
8ea1b28d73
commit
1202e4ad53
@ -1,138 +1,99 @@
|
||||
import 'dart:math';
|
||||
|
||||
var generator = PasswordGenerator();
|
||||
|
||||
String genPass() {
|
||||
generator.generate(8);
|
||||
return generator.getGeneratedValue();
|
||||
}
|
||||
|
||||
///Generates a password.
|
||||
///
|
||||
///The password [_generatedValue] is of a specified length, including letters [_letterGen] of mixed cases,
|
||||
///numbers [_numGen], and symbols[_symGen] depending on user choice.
|
||||
class PasswordGenerator {
|
||||
late bool _letterGen;
|
||||
late bool _numGen;
|
||||
late bool _symGen;
|
||||
late String _generatedValue;
|
||||
|
||||
///Constructor.
|
||||
///
|
||||
///[_letterGen] is true to make password generation possible from the opening of the application, and
|
||||
///[_generatedValue] is intialized to the value below so the text containing it can be first generated
|
||||
///upon users request
|
||||
PasswordGenerator() {
|
||||
_letterGen = true;
|
||||
_numGen = true;
|
||||
_symGen = false;
|
||||
_generatedValue = "Press Generate";
|
||||
}
|
||||
|
||||
///Call to generate a value, of [n] length
|
||||
void generate(int n) {
|
||||
//Discards the old value
|
||||
_generatedValue = "";
|
||||
|
||||
///Cannot generate a value without any character types selected
|
||||
if (!_letterGen && !_numGen && !_symGen) {
|
||||
_generatedValue = "No character type selected";
|
||||
return;
|
||||
Random _rnd = Random();
|
||||
|
||||
typedef StringGeneratorFunction = String Function();
|
||||
|
||||
class StringGenerators {
|
||||
static const letters = 'abcdefghijklmnopqrstuvwxyz';
|
||||
static const numbers = '1234567890';
|
||||
static const symbols = '_';
|
||||
|
||||
static String getRandomString(
|
||||
int length, {
|
||||
hasLowercaseLetters = false,
|
||||
hasUppercaseLetters = false,
|
||||
hasNumbers = false,
|
||||
hasSymbols = false,
|
||||
isStrict = false,
|
||||
}) {
|
||||
var chars = '';
|
||||
if (hasLowercaseLetters) chars += letters;
|
||||
if (hasUppercaseLetters) chars += letters.toUpperCase();
|
||||
if (hasNumbers) chars += numbers;
|
||||
if (hasSymbols) chars += symbols;
|
||||
|
||||
assert(chars.isNotEmpty, 'chart empty');
|
||||
|
||||
if (!isStrict) {
|
||||
return genString(length, chars);
|
||||
}
|
||||
|
||||
///'Randomly' selectes caracter type to generate and append [toAppend] to [_generatedValue]
|
||||
// ignore: unnecessary_statements
|
||||
for (n; n > 0; n--) {
|
||||
String? toAppend;
|
||||
var random = new Random();
|
||||
|
||||
///loops until a valid character is generated, meaning the user has to check the character value
|
||||
///to be generated. 'Randomly' picks a character type.
|
||||
while (toAppend == null) {
|
||||
int selector = random.nextInt(3);
|
||||
|
||||
if (selector == 0) {
|
||||
toAppend = _generateLetter();
|
||||
} else if (selector == 1) {
|
||||
toAppend = _generateNumber();
|
||||
} else {
|
||||
toAppend = _generateSymbol();
|
||||
}
|
||||
}
|
||||
|
||||
_generatedValue += toAppend;
|
||||
toAppend = null;
|
||||
var res = '';
|
||||
var loose = length;
|
||||
if (hasLowercaseLetters) {
|
||||
loose -= 1;
|
||||
res += genString(1, letters);
|
||||
}
|
||||
}
|
||||
|
||||
///Generates a letter when called.
|
||||
String _generateLetter() {
|
||||
if (!_letterGen) return '';
|
||||
|
||||
///Finds the integer value for the range between a-z and A-Z, with [base] UTF-16 value for lowercase letters and
|
||||
///[baseUpper] UTF-16 value for uppercase letters
|
||||
int base = "a".codeUnitAt(0);
|
||||
int baseUpper = "A".codeUnitAt(0);
|
||||
int maxRand = ("z".codeUnitAt(0) - base) + 1;
|
||||
Random random = new Random();
|
||||
|
||||
///Randomly selects between upper and lower case generation, randomly generates value from [maxRand], then adding base,
|
||||
///which creates a UTF-16 encoded character to be converted into a string of one character between a-z/A-Z.
|
||||
///This string is then returned.
|
||||
if (random.nextInt(2) == 0) {
|
||||
return String.fromCharCodes([random.nextInt(maxRand) + base]);
|
||||
} else {
|
||||
return String.fromCharCodes([random.nextInt(maxRand) + baseUpper]);
|
||||
if (hasUppercaseLetters) {
|
||||
loose -= 1;
|
||||
res += genString(1, letters.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
///Generates a number when called
|
||||
String? _generateNumber() {
|
||||
if (!_numGen) return null;
|
||||
|
||||
///Finds the integer value for the range between 0-9
|
||||
int base = "0".codeUnitAt(0);
|
||||
int maxRand = ("9".codeUnitAt(0) - base) + 1;
|
||||
Random random = new Random();
|
||||
|
||||
///Randomly generates value from [maxRand], then adding base, which creates a UTF-16 encoded character to be converted into a
|
||||
///string of one character between 0-9. This string is then returned.
|
||||
return String.fromCharCodes([random.nextInt(maxRand) + base]);
|
||||
}
|
||||
|
||||
///Generates a symbol when called
|
||||
String? _generateSymbol() {
|
||||
if (!_symGen) return null;
|
||||
|
||||
///Finds the integer value for the range between symbols !-.
|
||||
|
||||
///(note) which includes symbols !"#$%&'()*+,=.
|
||||
int base = "!".codeUnitAt(0);
|
||||
int maxRand = (".".codeUnitAt(0) - base) + 1;
|
||||
Random random = new Random();
|
||||
|
||||
///Randomly generates value from [maxRand], then adding base, which creates a UTF-16 encoded character to be
|
||||
///converted into a string of one character between !-. . This string is then returned.
|
||||
return String.fromCharCodes([random.nextInt(maxRand) + base]);
|
||||
}
|
||||
|
||||
///Toggles letter generation
|
||||
void checkLetterGen(bool value) {
|
||||
_letterGen = value;
|
||||
}
|
||||
if (hasNumbers) {
|
||||
loose -= 1;
|
||||
res += genString(1, numbers.toUpperCase());
|
||||
}
|
||||
if (hasSymbols) {
|
||||
loose -= 1;
|
||||
res += genString(1, symbols);
|
||||
}
|
||||
res += genString(loose, chars);
|
||||
|
||||
///Toggles number generation
|
||||
void checkNumGen(bool value) {
|
||||
_numGen = value;
|
||||
var shuffledlist = res.split('')..shuffle();
|
||||
return shuffledlist.join();
|
||||
}
|
||||
|
||||
///Toggles symbol generation
|
||||
void checkSymGen(bool value) {
|
||||
_symGen = value;
|
||||
static String genString(int length, String chars) {
|
||||
return String.fromCharCodes(
|
||||
Iterable.generate(
|
||||
length,
|
||||
(_) => chars.codeUnitAt(
|
||||
_rnd.nextInt(chars.length),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
///Returns the generated value to be used by generator app
|
||||
String getGeneratedValue() {
|
||||
return _generatedValue;
|
||||
}
|
||||
static StringGeneratorFunction userPassword = () => getRandomString(
|
||||
8,
|
||||
hasLowercaseLetters: true,
|
||||
hasUppercaseLetters: true,
|
||||
hasNumbers: true,
|
||||
isStrict: true,
|
||||
);
|
||||
|
||||
static StringGeneratorFunction passwordSalt = () => getRandomString(
|
||||
8,
|
||||
hasLowercaseLetters: true,
|
||||
);
|
||||
|
||||
static StringGeneratorFunction simpleId = () => getRandomString(
|
||||
5,
|
||||
hasLowercaseLetters: true,
|
||||
);
|
||||
|
||||
static StringGeneratorFunction dbPassword = () => getRandomString(
|
||||
40,
|
||||
hasLowercaseLetters: true,
|
||||
hasUppercaseLetters: true,
|
||||
hasNumbers: true,
|
||||
hasSymbols: true,
|
||||
);
|
||||
|
||||
static StringGeneratorFunction dbStorageName = () => getRandomString(
|
||||
6,
|
||||
hasLowercaseLetters: true,
|
||||
hasUppercaseLetters: true,
|
||||
hasNumbers: true,
|
||||
);
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
import 'dart:math';
|
||||
|
||||
const _chars =
|
||||
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890_';
|
||||
Random _rnd = Random();
|
||||
|
||||
String getRandomString(int length, [chars = _chars]) => String.fromCharCodes(
|
||||
Iterable.generate(
|
||||
length,
|
||||
(_) => chars.codeUnitAt(
|
||||
_rnd.nextInt(chars.length),
|
||||
),
|
||||
),
|
||||
);
|
@ -1,30 +1,122 @@
|
||||
// This is a basic Flutter widget test.
|
||||
//
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// utility that Flutter provides. For example, you can send tap and scroll
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:selfprivacy/main.dart';
|
||||
import 'package:selfprivacy/utils/password_generator.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(MyApp());
|
||||
group('StringGenerators', () {
|
||||
group('Basic', () {
|
||||
test('assert chart empty', () {
|
||||
expect(() {
|
||||
StringGenerators.getRandomString(8);
|
||||
}, throwsAssertionError);
|
||||
});
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
test('only lowercase string', () {
|
||||
var length = 8;
|
||||
var generatedString =
|
||||
StringGenerators.getRandomString(length, hasLowercaseLetters: true);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
expect(generatedString, isNot(matches(regExpNewLines)));
|
||||
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
|
||||
expect(generatedString, isNot(matches(regExpNumbers)));
|
||||
expect(generatedString, isNot(matches(regExpUppercaseLetters)));
|
||||
expect(generatedString, isNot(matches(regExpSymbols)));
|
||||
expect(generatedString.length, equals(length));
|
||||
expect(generatedString, matches(regExpLowercaseLetters));
|
||||
});
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
test('only uppercase string', () {
|
||||
var length = 8;
|
||||
var generatedString = StringGenerators.getRandomString(length,
|
||||
hasLowercaseLetters: false, hasUppercaseLetters: true);
|
||||
|
||||
expect(generatedString, isNot(matches(regExpNewLines)));
|
||||
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
|
||||
expect(generatedString, isNot(matches(regExpNumbers)));
|
||||
expect(generatedString, isNot(matches(regExpLowercaseLetters)));
|
||||
expect(generatedString, isNot(matches(regExpSymbols)));
|
||||
expect(generatedString.length, equals(length));
|
||||
expect(generatedString, matches(regExpUppercaseLetters));
|
||||
});
|
||||
|
||||
test('only numbers string', () {
|
||||
var length = 8;
|
||||
var generatedString = StringGenerators.getRandomString(length,
|
||||
hasLowercaseLetters: false,
|
||||
hasUppercaseLetters: false,
|
||||
hasNumbers: true);
|
||||
|
||||
expect(generatedString, isNot(matches(regExpNewLines)));
|
||||
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
|
||||
expect(generatedString, isNot(matches(regExpUppercaseLetters)));
|
||||
expect(generatedString, isNot(matches(regExpLowercaseLetters)));
|
||||
expect(generatedString, isNot(matches(regExpSymbols)));
|
||||
expect(generatedString.length, equals(length));
|
||||
expect(generatedString, matches(regExpNumbers));
|
||||
});
|
||||
|
||||
test('only symbols string', () {
|
||||
var length = 8;
|
||||
var generatedString = StringGenerators.getRandomString(
|
||||
length,
|
||||
hasLowercaseLetters: false,
|
||||
hasUppercaseLetters: false,
|
||||
hasNumbers: false,
|
||||
hasSymbols: true,
|
||||
);
|
||||
|
||||
expect(generatedString, isNot(matches(regExpNewLines)));
|
||||
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
|
||||
expect(generatedString, isNot(matches(regExpUppercaseLetters)));
|
||||
expect(generatedString, isNot(matches(regExpLowercaseLetters)));
|
||||
expect(generatedString, isNot(matches(regExpNumbers)));
|
||||
expect(generatedString.length, equals(length));
|
||||
expect(generatedString, matches(regExpSymbols));
|
||||
});
|
||||
});
|
||||
|
||||
group('Strict mode', () {
|
||||
test('All', () {
|
||||
var length = 5;
|
||||
var generatedString = StringGenerators.getRandomString(length,
|
||||
hasLowercaseLetters: true,
|
||||
hasUppercaseLetters: true,
|
||||
hasNumbers: true,
|
||||
hasSymbols: true,
|
||||
isStrict: true);
|
||||
|
||||
expect(generatedString, isNot(matches(regExpNewLines)));
|
||||
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
|
||||
expect(generatedString, matches(regExpLowercaseLetters));
|
||||
expect(generatedString, matches(regExpUppercaseLetters));
|
||||
expect(generatedString, matches(regExpNumbers));
|
||||
expect(generatedString, matches(regExpSymbols));
|
||||
expect(generatedString.length, equals(length));
|
||||
});
|
||||
test('Lowercase letters and numbers', () {
|
||||
var length = 3;
|
||||
var generatedString = StringGenerators.getRandomString(length,
|
||||
hasLowercaseLetters: true,
|
||||
hasUppercaseLetters: false,
|
||||
hasNumbers: true,
|
||||
hasSymbols: false,
|
||||
isStrict: true);
|
||||
|
||||
expect(generatedString, isNot(matches(regExpNewLines)));
|
||||
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
|
||||
expect(generatedString, isNot(matches(regExpUppercaseLetters)));
|
||||
expect(generatedString, isNot(matches(regExpSymbols)));
|
||||
expect(generatedString, matches(regExpLowercaseLetters));
|
||||
expect(generatedString, matches(regExpNumbers));
|
||||
expect(generatedString.length, equals(length));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var regExpNewLines = RegExp(r"[\n\r]+");
|
||||
var regExpWhiteSpaces = RegExp(r"[\s]+");
|
||||
var regExpUppercaseLetters = RegExp(r"[A-Z]");
|
||||
var regExpLowercaseLetters = RegExp(r"[a-z]");
|
||||
var regExpNumbers = RegExp(r"[0-9]");
|
||||
var regExpSymbols = RegExp(r'(?:_|[^\w\s])+');
|
||||
|
Loading…
Reference in New Issue