mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-14 14:02:28 +00:00
131 lines
5.5 KiB
Objective-C
131 lines
5.5 KiB
Objective-C
//
|
|
// NSString+MPPasswordCreation.m
|
|
// MacPass
|
|
//
|
|
// Created by Michael Starke on 29.03.13.
|
|
// Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
//
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#import "NSString+MPPasswordCreation.h"
|
|
#import "KeePassKit/KeePassKit.h"
|
|
|
|
#import "NSString+MPComposedCharacterAdditions.h"
|
|
#import "MPSettingsHelper.h"
|
|
|
|
NSString *const kMPLowercaseLetterCharacters = @"abcdefghijklmnopqrstuvwxyz";
|
|
NSString *const kMPNumberCharacters = @"1234567890";
|
|
NSString *const kMPSymbolCharacters = @"!$%&\\|/<>(){}[]=?*'+#-_.:,;";
|
|
|
|
static NSString *allowedCharactersString(MPPasswordCharacterFlags flags) {
|
|
NSMutableString *characterString = [NSMutableString stringWithCapacity:30];
|
|
if(flags & MPPasswordCharactersLowerCase) {
|
|
[characterString appendString:kMPLowercaseLetterCharacters];
|
|
}
|
|
if(flags & MPPasswordCharactersUpperCase) {
|
|
[characterString appendString:[kMPLowercaseLetterCharacters uppercaseString]];
|
|
}
|
|
if(flags & MPPasswordCharactersNumbers) {
|
|
[characterString appendString:kMPNumberCharacters];
|
|
}
|
|
if(flags & MPPasswordCharactersSymbols){
|
|
[characterString appendString:kMPSymbolCharacters];
|
|
}
|
|
return characterString;
|
|
}
|
|
|
|
static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* customCharacters){
|
|
NSMutableString* mergedCharacters = [[NSMutableString alloc] init];
|
|
[mergedCharacters appendString:baseCharacters];
|
|
[customCharacters enumerateSubstringsInRange: NSMakeRange(0, customCharacters.length)
|
|
options: NSStringEnumerationByComposedCharacterSequences
|
|
usingBlock: ^(NSString *inSubstring, NSRange inSubstringRange, NSRange inEnclosingRange, BOOL *outStop) {
|
|
if(0 == [mergedCharacters rangeOfString:inSubstring].length){
|
|
[mergedCharacters appendString:inSubstring];
|
|
}
|
|
}];
|
|
return [NSString stringWithString:mergedCharacters];
|
|
}
|
|
|
|
@implementation NSString (MPPasswordCreation)
|
|
|
|
+ (NSString *)passwordFromString:(NSString *)source length:(NSUInteger)length {
|
|
NSMutableString *password = [[NSMutableString alloc] initWithCapacity:length];
|
|
while(password.composedCharacterLength < length) {
|
|
[password appendString:source.randomCharacter];
|
|
}
|
|
return password;
|
|
}
|
|
|
|
+ (NSString *)passwordWithCharactersets:(MPPasswordCharacterFlags)allowedCharacters
|
|
withCustomCharacters:(NSString*)customCharacters
|
|
length:(NSUInteger)length {
|
|
NSMutableString *password = [NSMutableString stringWithCapacity:length];
|
|
NSString *characters = mergeWithoutDuplicates(
|
|
allowedCharactersString(allowedCharacters),
|
|
customCharacters);
|
|
while(password.composedCharacterLength < length) {
|
|
NSString *randomCharacter = characters.randomCharacter;
|
|
if(randomCharacter.length > 0) {
|
|
[password appendString:randomCharacter];
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
return password;
|
|
}
|
|
|
|
+ (NSString *)passwordWithDefaultSettings {
|
|
/* generate and pre-fill password using default password creation settings */
|
|
NSUInteger passwordLength = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyDefaultPasswordLength];
|
|
MPPasswordCharacterFlags characterFlags = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyPasswordCharacterFlags];
|
|
BOOL useCustomString = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPasswordUseCustomString];
|
|
NSString *customString = [NSUserDefaults.standardUserDefaults stringForKey:kMPSettingsKeyPasswordCustomString];
|
|
|
|
if(useCustomString && customString.length > 0) {
|
|
return [customString passwordWithLength:passwordLength];
|
|
}
|
|
return [NSString passwordWithCharactersets:characterFlags
|
|
withCustomCharacters:@""
|
|
length:passwordLength];
|
|
}
|
|
|
|
- (NSString *)passwordWithLength:(NSUInteger)length {
|
|
return [NSString passwordFromString:self length:length];
|
|
}
|
|
|
|
- (NSString *)randomCharacter {
|
|
if(self.length == 0) {
|
|
return nil;
|
|
}
|
|
return [self composedCharacterAtIndex:arc4random_uniform((int)[self length])];
|
|
}
|
|
|
|
- (CGFloat)entropyWhithPossibleCharacterSet:(MPPasswordCharacterFlags)allowedCharacters orCustomCharacters:(NSString *)customCharacters {
|
|
NSString *characters = nil;
|
|
if([NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPasswordUseCustomString] && nil != customCharacters) {
|
|
characters = mergeWithoutDuplicates(allowedCharactersString(allowedCharacters), customCharacters);
|
|
}
|
|
else {
|
|
characters = allowedCharactersString(allowedCharacters);
|
|
}
|
|
CGFloat alphabetCount = characters.composedCharacterLength;
|
|
CGFloat passwordLength = self.composedCharacterLength;
|
|
return passwordLength * ( log10(alphabetCount) / log10(2) );
|
|
}
|
|
@end
|