Fixed bug in entropy calculation when using mixed character sets. Added enforce groups button to UI

This commit is contained in:
Michael Starke
2019-01-31 13:13:05 +01:00
parent 6068260abb
commit 6a1f8e0472
4 changed files with 106 additions and 64 deletions

View File

@@ -10,6 +10,7 @@
<connections>
<outlet property="customButton" destination="468" id="598"/>
<outlet property="customCharactersTextField" destination="411" id="479"/>
<outlet property="ensureCharacterFromEachGroupButton" destination="RDM-JY-oF9" id="btK-Gf-vpP"/>
<outlet property="entropyIndicator" destination="635" id="676"/>
<outlet property="entropyTextField" destination="652" id="675"/>
<outlet property="lowerCaseButton" destination="456" id="593"/>
@@ -28,11 +29,11 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="1">
<rect key="frame" x="0.0" y="0.0" width="351" height="291"/>
<rect key="frame" x="0.0" y="0.0" width="351" height="316"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="148">
<rect key="frame" x="18" y="251" width="66" height="17"/>
<rect key="frame" x="18" y="276" width="66" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Password:" id="149">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -40,7 +41,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="152">
<rect key="frame" x="90" y="247" width="201" height="24"/>
<rect key="frame" x="90" y="272" width="201" height="24"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="621"/>
</constraints>
@@ -51,11 +52,11 @@
</textFieldCell>
</textField>
<slider verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="173">
<rect key="frame" x="88" y="221" width="205" height="19"/>
<rect key="frame" x="88" y="246" width="205" height="19"/>
<sliderCell key="cell" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="above" sliderType="linear" id="174"/>
</slider>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="178">
<rect key="frame" x="18" y="223" width="66" height="17"/>
<rect key="frame" x="18" y="248" width="66" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Length:" id="179">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -63,7 +64,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="182">
<rect key="frame" x="299" y="219" width="32" height="22"/>
<rect key="frame" x="299" y="244" width="32" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="32" id="eVc-Kg-bCi"/>
</constraints>
@@ -75,13 +76,13 @@
</textFieldCell>
</textField>
<box autoresizesSubviews="NO" borderType="line" title="Allowed Characters" translatesAutoresizingMaskIntoConstraints="NO" id="332">
<rect key="frame" x="17" y="88" width="317" height="94"/>
<rect key="frame" x="17" y="88" width="317" height="119"/>
<view key="contentView" id="f93-Su-hga">
<rect key="frame" x="3" y="3" width="311" height="76"/>
<rect key="frame" x="3" y="3" width="311" height="101"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="411">
<rect key="frame" x="16" y="17" width="279" height="22"/>
<rect key="frame" x="16" y="42" width="279" height="22"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="412" customClass="HNHUITextFieldCell">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -89,7 +90,7 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="452">
<rect key="frame" x="16" y="47" width="36" height="19"/>
<rect key="frame" x="16" y="72" width="36" height="19"/>
<buttonCell key="cell" type="roundRect" title="A-Z" bezelStyle="roundedRect" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="453">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="cellTitle"/>
@@ -99,7 +100,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="456">
<rect key="frame" x="60" y="47" width="33" height="19"/>
<rect key="frame" x="60" y="72" width="33" height="19"/>
<buttonCell key="cell" type="roundRect" title="a-z" bezelStyle="roundedRect" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="457">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="cellTitle"/>
@@ -109,7 +110,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" tag="4" translatesAutoresizingMaskIntoConstraints="NO" id="460">
<rect key="frame" x="101" y="47" width="35" height="19"/>
<rect key="frame" x="101" y="72" width="35" height="19"/>
<buttonCell key="cell" type="roundRect" title="0-9" bezelStyle="roundedRect" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="461">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="cellTitle"/>
@@ -119,7 +120,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" tag="8" translatesAutoresizingMaskIntoConstraints="NO" id="464">
<rect key="frame" x="144" y="47" width="32" height="19"/>
<rect key="frame" x="144" y="72" width="32" height="19"/>
<buttonCell key="cell" type="roundRect" title="#!?" bezelStyle="roundedRect" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="465">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="cellTitle"/>
@@ -129,7 +130,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="468">
<rect key="frame" x="184" y="47" width="58" height="19"/>
<rect key="frame" x="184" y="72" width="58" height="19"/>
<buttonCell key="cell" type="roundRect" title="Custom" bezelStyle="roundedRect" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="469">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="cellTitle"/>
@@ -138,7 +139,20 @@
<action selector="_toggleCharacters:" target="-2" id="5CP-8c-RKX"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RDM-JY-oF9">
<rect key="frame" x="14" y="18" width="229" height="18"/>
<buttonCell key="cell" type="check" title="Ensure character from each group" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="CMc-Uh-Fo5">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="RDM-JY-oF9" secondAttribute="trailing" constant="20" symbolic="YES" id="04d-ak-mHi"/>
<constraint firstItem="RDM-JY-oF9" firstAttribute="top" secondItem="411" secondAttribute="bottom" constant="8" symbolic="YES" id="eDq-kw-W3j"/>
<constraint firstItem="RDM-JY-oF9" firstAttribute="leading" secondItem="411" secondAttribute="leading" id="lwy-YZ-Vxl"/>
<constraint firstAttribute="bottom" secondItem="RDM-JY-oF9" secondAttribute="bottom" constant="20" symbolic="YES" id="rS3-s4-ibM"/>
</constraints>
</view>
<constraints>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="468" secondAttribute="trailing" constant="16" id="1AP-Bk-63Z"/>
@@ -147,7 +161,6 @@
<constraint firstItem="468" firstAttribute="leading" secondItem="464" secondAttribute="trailing" constant="8" symbolic="YES" id="I61-T5-YTD"/>
<constraint firstItem="460" firstAttribute="leading" secondItem="456" secondAttribute="trailing" constant="8" symbolic="YES" id="IEY-Ge-pYv"/>
<constraint firstItem="468" firstAttribute="top" secondItem="332" secondAttribute="top" constant="25" id="NAr-SD-lu0"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="411" secondAttribute="bottom" constant="16" id="O0V-4Y-bhc"/>
<constraint firstItem="456" firstAttribute="top" secondItem="332" secondAttribute="top" constant="25" id="QYc-6i-WKC"/>
<constraint firstItem="460" firstAttribute="top" secondItem="332" secondAttribute="top" constant="25" id="ZaM-QU-hcG"/>
<constraint firstItem="456" firstAttribute="leading" secondItem="452" secondAttribute="trailing" constant="8" symbolic="YES" id="bFo-86-Qj1"/>
@@ -159,7 +172,7 @@
</constraints>
</box>
<button verticalHuggingPriority="750" horizontalCompressionResistancePriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="494">
<rect key="frame" x="231" y="19" width="100" height="23"/>
<rect key="frame" x="231.5" y="19" width="100" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Use Password" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="495">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -176,7 +189,7 @@
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="509">
<rect key="frame" x="299" y="248" width="32" height="23"/>
<rect key="frame" x="298.5" y="273" width="33" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSRefreshTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="510">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -186,7 +199,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="613">
<rect key="frame" x="167" y="19" width="56" height="23"/>
<rect key="frame" x="168.5" y="19" width="56" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="614">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -196,11 +209,11 @@
</connections>
</button>
<levelIndicator verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="635">
<rect key="frame" x="90" y="188" width="173" height="18"/>
<rect key="frame" x="90" y="213" width="173" height="18"/>
<levelIndicatorCell key="cell" alignment="left" doubleValue="10" maxValue="90" warningValue="55" criticalValue="30" levelIndicatorStyle="continuousCapacity" id="636" customClass="HNHUILevelIndicatorCell"/>
</levelIndicator>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="646">
<rect key="frame" x="18" y="190" width="66" height="17"/>
<rect key="frame" x="18" y="215" width="66" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Entropy:" id="647">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -208,7 +221,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="652">
<rect key="frame" x="269" y="190" width="64" height="17"/>
<rect key="frame" x="269" y="215" width="64" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="25000 bit" id="653">
<numberFormatter key="formatter" formatterBehavior="custom10_4" positiveFormat="# bit" negativeFormat="# bit" usesGroupingSeparator="NO" paddingCharacter="*" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="309" decimalSeparator="," groupingSeparator="." currencyDecimalSeparator="," plusSign="+" minusSign="-" notANumberSymbol="NaN" perMillSymbol="‰" percentSymbol="%" exponentSymbol="E" positivePrefix="" positiveSuffix=" bit" negativePrefix="-" negativeSuffix=" bit" id="681"/>
<font key="font" metaFont="system"/>
@@ -217,7 +230,7 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yil-UB-jtO">
<rect key="frame" x="20" y="19" width="82" height="23"/>
<rect key="frame" x="19.5" y="19" width="82" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Set Default" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Wvs-Md-Ob8">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -273,14 +286,14 @@
<constraint firstItem="148" firstAttribute="trailing" secondItem="178" secondAttribute="trailing" id="KpM-xy-ZTB"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="4yb-SC-vau" secondAttribute="trailing" constant="20" symbolic="YES" id="OnS-dH-uyZ"/>
<constraint firstItem="509" firstAttribute="leading" secondItem="182" secondAttribute="leading" id="QZ5-Ge-aq8"/>
<constraint firstItem="613" firstAttribute="top" secondItem="4yb-SC-vau" secondAttribute="bottom" constant="8" symbolic="YES" id="SoR-gh-uhq"/>
<constraint firstItem="613" firstAttribute="top" relation="greaterThanOrEqual" secondItem="4yb-SC-vau" secondAttribute="bottom" constant="8" symbolic="YES" id="SoR-gh-uhq"/>
<constraint firstAttribute="bottom" secondItem="yil-UB-jtO" secondAttribute="bottom" constant="20" id="eYK-Hw-fyy"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="500" secondAttribute="trailing" constant="20" symbolic="YES" id="iUl-yt-JbV"/>
<constraint firstItem="646" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="jPa-QR-GAy"/>
<constraint firstItem="178" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="pAc-di-F68"/>
<constraint firstItem="500" firstAttribute="leading" secondItem="4yb-SC-vau" secondAttribute="leading" id="xv1-5v-Ljh"/>
</constraints>
<point key="canvasLocation" x="-287" y="-285"/>
<point key="canvasLocation" x="-61.5" y="-402"/>
</customView>
</objects>
<resources>

View File

@@ -58,23 +58,25 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
@property (nonatomic, copy) NSString *password;
@property (copy) NSString *generatedPassword;
@property (weak) IBOutlet NSTextField *passwordTextField;
@property (weak) IBOutlet NSTextField *passwordLengthTextField;
@property (weak) IBOutlet NSTextField *customCharactersTextField;
@property (weak) IBOutlet NSSlider *passwordLengthSlider;
@property (weak) IBOutlet NSButton *shouldCopyPasswordToPasteboardButton;
@property (weak) IBOutlet NSButton *upperCaseButton;
@property (weak) IBOutlet NSButton *lowerCaseButton;
@property (weak) IBOutlet NSButton *numbersButton;
@property (weak) IBOutlet NSButton *symbolsButton;
@property (weak) IBOutlet NSButton *customButton;
@property (weak) IBOutlet NSButton *setDefaultButton;
@property (weak) IBOutlet NSTextField *entropyTextField;
@property (weak) IBOutlet NSLevelIndicator *entropyIndicator;
@property (weak) IBOutlet NSButton *useEntryDefaultsButton;
@property (strong) IBOutlet NSTextField *passwordTextField;
@property (strong) IBOutlet NSTextField *passwordLengthTextField;
@property (strong) IBOutlet NSTextField *customCharactersTextField;
@property (strong) IBOutlet NSSlider *passwordLengthSlider;
@property (strong) IBOutlet NSButton *shouldCopyPasswordToPasteboardButton;
@property (strong) IBOutlet NSButton *upperCaseButton;
@property (strong) IBOutlet NSButton *lowerCaseButton;
@property (strong) IBOutlet NSButton *numbersButton;
@property (strong) IBOutlet NSButton *symbolsButton;
@property (strong) IBOutlet NSButton *customButton;
@property (strong) IBOutlet NSButton *ensureCharacterFromEachGroupButton;
@property (strong) IBOutlet NSButton *setDefaultButton;
@property (strong) IBOutlet NSTextField *entropyTextField;
@property (strong) IBOutlet NSLevelIndicator *entropyIndicator;
@property (strong) IBOutlet NSButton *useEntryDefaultsButton;
@property (nonatomic, copy) NSString *customString;
@property (nonatomic, assign) BOOL useCustomString;
@property (nonatomic, assign) BOOL useCharacterFromEachGroup;
@property (nonatomic, assign) NSUInteger passwordLength;
@property (nonatomic, assign) CGFloat entropy;
@@ -96,6 +98,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
_entropy = 0.0;
_useEntryDefaults = NO;
_allowsEntryDefaults = NO;
_useCharacterFromEachGroup = NO;
[self _setupDefaults];
}
return self;
@@ -122,18 +125,20 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
[self.entropyIndicator bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(entropy)) options:nil];
[self.entropyTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(entropy)) options:nil];
[self.customCharactersTextField setDelegate:self];
self.customCharactersTextField.delegate = self;
[self.customButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(useCustomString)) options:nil];
[self.ensureCharacterFromEachGroupButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(useCharacterFromEachGroup)) options:nil];
NSString *copyToPasteBoardKeyPath = [MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyCopyGeneratedPasswordToClipboard];
NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController];
NSUserDefaultsController *defaultsController = NSUserDefaultsController.sharedUserDefaultsController;
[self.shouldCopyPasswordToPasteboardButton bind:NSValueBinding toObject:defaultsController withKeyPath:copyToPasteBoardKeyPath options:nil];
if(self.allowsEntryDefaults) {
[self.useEntryDefaultsButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(useEntryDefaults)) options:nil];
}
else {
[self.useEntryDefaultsButton setEnabled:self.allowsEntryDefaults];
self.useEntryDefaultsButton.enabled = self.allowsEntryDefaults;
}
self.numbersButton.tag = MPPasswordCharactersNumbers;
@@ -166,17 +171,17 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
- (IBAction)_generatePassword:(id)sender {
self.password = [NSString passwordWithCharactersets:self.characterFlags
withCustomCharacters:self._customCharacters
ensureOccurence:NO
ensureOccurence:self.useCharacterFromEachGroup
length:self.passwordLength];
}
- (NSString*)_customCharacters{
if(self.useCustomString && self.customCharactersTextField.stringValue.length > 0) {
return self.customCharactersTextField.stringValue;
}
else{
return @"";
}
return self.customCharactersTextField.stringValue;
}
else{
return @"";
}
}
@@ -222,7 +227,8 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
entryDefaults[kMPSettingsKeyDefaultPasswordLength] = @(self.passwordLength);
entryDefaults[kMPSettingsKeyPasswordCharacterFlags] = @(self.characterFlags);
entryDefaults[kMPSettingsKeyPasswordUseCustomString] = @(self.useCustomString);
entryDefaults[kMPSettingsKeyPasswordCustomString] = [self.customCharactersTextField stringValue];
entryDefaults[kMPSettingsKeyPasswordCustomString] = self.customCharactersTextField.stringValue;
entryDefaults[kMPSettingsKeyPasswordEnsureOccurance] = @(self.useCharacterFromEachGroup);
NSMutableDictionary *availableDefaults = [[self _availableEntryDefaults] mutableCopy];
if(!availableDefaults) {
availableDefaults = [[NSMutableDictionary alloc] initWithCapacity:1];
@@ -234,7 +240,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
[NSUserDefaults.standardUserDefaults setInteger:self.passwordLength forKey:kMPSettingsKeyDefaultPasswordLength];
[NSUserDefaults.standardUserDefaults setInteger:self.characterFlags forKey:kMPSettingsKeyPasswordCharacterFlags];
[NSUserDefaults.standardUserDefaults setBool:self.useCustomString forKey:kMPSettingsKeyPasswordUseCustomString];
[NSUserDefaults.standardUserDefaults setObject:[self.customCharactersTextField stringValue] forKey:kMPSettingsKeyPasswordCustomString];
[NSUserDefaults.standardUserDefaults setObject:self.customCharactersTextField.stringValue forKey:kMPSettingsKeyPasswordCustomString];
}
else {
NSLog(@"Cannot set password generator defaults. Inconsistent state. Aborting.");
@@ -278,7 +284,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
if(![_password isEqualToString:password]) {
_password = [password copy];
NSString *customString = self.useCustomString ? self.customCharactersTextField.stringValue : nil;
self.entropy = [password entropyWhithPossibleCharacterSet:self.characterFlags orCustomCharacters:customString];
self.entropy = [password entropyWhithPossibleCharacterSet:self.characterFlags andCustomCharacters:customString];
}
}
@@ -294,6 +300,15 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
if(self.passwordLength != passwordLength) {
self.setDefaultButton.enabled = YES;
_passwordLength = passwordLength;
[self _resetCharacters];
[self _generatePassword:nil];
}
}
- (void)setUseCharacterFromEachGroup:(BOOL)useCharacterFromEachGroup {
if(self.useCharacterFromEachGroup != useCharacterFromEachGroup) {
_useCharacterFromEachGroup = useCharacterFromEachGroup;
[self _resetCharacters];
[self _generatePassword:nil];
}
}
@@ -341,12 +356,14 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
self.characterFlags = [entryDefaults[kMPSettingsKeyPasswordCharacterFlags] integerValue];
self.useCustomString = [entryDefaults[kMPSettingsKeyPasswordUseCustomString] boolValue];
self.customString = entryDefaults[kMPSettingsKeyPasswordCustomString];
self.useCharacterFromEachGroup = [entryDefaults[kMPSettingsKeyPasswordEnsureOccurance] boolValue];
}
else {
self.passwordLength = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyDefaultPasswordLength];
self.characterFlags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyPasswordCharacterFlags];
self.useCustomString = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyPasswordUseCustomString];
self.customString = [[NSUserDefaults standardUserDefaults] stringForKey:kMPSettingsKeyPasswordCustomString];
self.passwordLength = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyDefaultPasswordLength];
self.characterFlags = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyPasswordCharacterFlags];
self.useCustomString = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPasswordUseCustomString];
self.customString = [NSUserDefaults.standardUserDefaults stringForKey:kMPSettingsKeyPasswordCustomString];
self.useCharacterFromEachGroup = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPasswordEnsureOccurance];
}
}
@@ -374,5 +391,22 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
self.lowerCaseButton.state = (userLowercase ? NSOnState : NSOffState);
self.numbersButton.state = (useNumbers ? NSOnState : NSOffState);
self.symbolsButton.state = (useSymbols ? NSOnState : NSOffState);
// ensure minimum character lenght
if(self.useCharacterFromEachGroup) {
NSUInteger minimumPasswordLength = 0;
NSUInteger activeFlags = self.characterFlags;
while(activeFlags > 0) {
if(activeFlags & 1) {
minimumPasswordLength++;
}
activeFlags >>= 1;
}
if(self.passwordLength < minimumPasswordLength) {
self.passwordLength = minimumPasswordLength;
}
}
}
@end

View File

@@ -77,13 +77,13 @@ typedef NS_OPTIONS(NSUInteger, MPPasswordCharacterFlags) {
/**
* Calculates the entropy of the receiver based on the allowed characters. The calculation considers the characters chosen randomly.
* If the password supplied was not created randomly based on the full character set, the calculated entropy is NOT correct.
* Do NOT use this method to estimate unknown passwords
* Do NOT use this method to estimate passwords with unknown alphabet
*
* @param allowedCharacters set of allowed Characters
* @param customCharacters alternative string of unique allowed characters (String is not stripped of duplicates!)
* @param customCharacters additional custom string of allowed characters.
*
* @return entropy of the receiver as bits
*/
- (CGFloat)entropyWhithPossibleCharacterSet:(MPPasswordCharacterFlags)allowedCharacters orCustomCharacters:(NSString *)customCharacters;
- (CGFloat)entropyWhithPossibleCharacterSet:(MPPasswordCharacterFlags)allowedCharacters andCustomCharacters:(NSString *)customCharacters;
@end

View File

@@ -114,14 +114,9 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust
return [self composedCharacterAtIndex:arc4random_uniform((int)self.composedCharacterLength)];
}
- (CGFloat)entropyWhithPossibleCharacterSet:(MPPasswordCharacterFlags)allowedCharacters orCustomCharacters:(NSString *)customCharacters {
- (CGFloat)entropyWhithPossibleCharacterSet:(MPPasswordCharacterFlags)allowedCharacters andCustomCharacters:(NSString *)customCharacters {
NSString *characters = nil;
if([NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPasswordUseCustomString] && nil != customCharacters) {
characters = mergeWithoutDuplicates(allowedCharactersString(allowedCharacters), customCharacters);
}
else {
characters = allowedCharactersString(allowedCharacters);
}
characters = mergeWithoutDuplicates(allowedCharactersString(allowedCharacters), customCharacters);
CGFloat alphabetCount = characters.composedCharacterLength;
CGFloat passwordLength = self.composedCharacterLength;
return passwordLength * ( log10(alphabetCount) / log10(2) );