XKCD Password Generator (xpg)
~~~ $ xpg -h xpg 0.1.0 xkcd password generator
USAGE: xpg [FLAGS] [OPTIONS]
FLAGS: --analyze Analyze -h, --help Prints help information -V, --version Prints version information
OPTIONS:
-c, --count
~~~ $ xpg -V xpg 0.1.0 ~~~
~~~ $ xpg BroughtStoneBelfastDegree ~~~
~~~ $ xpg -c 10 AugustDoesEngineSystem MarylandVariousEveryoneSchool EnglishTableSubjectBritain EarsLaborBlackSeem WheatWashQuarterSaturday DiedSoldiersFromVermont TeachAdditionPersonForeign FifthTakeBuildDetails MoleculesWhichChinaSelf ForeignNoticePeaceDetermine ~~~
~~~ $ xpg -w 8 CostSectionGainSpendBroughtDropBuildingSeat ~~~
~~~ $ xpg -w 8 -c 10 TellProudManyDifferenceAgreeAboutLongSweden SoundPaintBulgariaThousandsBreakSpokeBeanArticle HistoryPairSorryPainItselfSubstancesPortugalMarch CollegeCoveredJumpTrustScaleDistantFreshEdge StarEdgeRolledHappenKeepWedgeMillionWhite WearMindFamilyPreparedHardAlmostEnergyTuesday ThankWhenEnjoyCollegeMeetingDrawCaughtCold ReachMontanaPrintedFeetNoseYardBallHand EnglandBicycleLiftedStrikeSleepMightWheatSort JordanHuntCertainReadQueenNieceEngineExpect ~~~
~~~ $ xpg --analyze * Word list length: 1,259 * Words in password: 4 * Total permutations (without repetition): 2,500,525,503,024
```
1,259! / (1,259 - 4)!
1,259! / 1,255!
2,500,525,503,024
```
Words | Permutations ---|---: 1 | 1,259 2 | 1,583,822 3 | 1,990,864,254 4 | 2,500,525,503,024 5 | 3,138,159,506,295,120 6 | 3,935,252,020,894,080,480 7 | 4,930,870,782,180,282,841,440 8 | 6,173,450,219,289,714,117,482,880 ... | ...
~~~
~~~ $ xpg --analyze -w 8 * Word list length: 1,259 * Words in password: 8 * Total permutations (without repetition): 6,173,450,219,289,714,117,482,880
```
1,259! / (1,259 - 8)!
1,259! / 1,251!
6,173,450,219,289,714,117,482,880
```
Words | Permutations ---|---: 1 | 1,259 2 | 1,583,822 3 | 1,990,864,254 4 | 2,500,525,503,024 5 | 3,138,159,506,295,120 6 | 3,935,252,020,894,080,480 7 | 4,930,870,782,180,282,841,440 8 | 6,173,450,219,289,714,117,482,880 ... | ...
~~~
choose_multiple
xpg
functionxpg!
macro to enable optional word count argumentWord list comes from Bart Busschots' HSXKPasswd Perl module (GitHub, CPAN: Crypt::HSXKPasswd), specifically lib/Crypt/HSXKPasswd/Dictionary/EN.pm@1d88564:38
~~~ $ cargo test
running 11 tests test tests::xpgmacrocannotreturnzerowords ... ok test tests::xpgcannotreturnzerowords ... ok test tests::xpgcanreturnoneword ... ok test tests::xpgmacrocanreturnoneword ... ok test tests::xpgcanreturnthreewords ... ok test tests::xpgmacrocanreturnthreewords ... ok test tests::xpgcanreturnfourwords ... ok test tests::defaultxpgmacroreturnsfourwords ... ok test tests::xpgcanreturnfivewords ... ok test tests::xpgmacrocanreturnfourwords ... ok test tests::xpgmacrocanreturnfivewords ... ok
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
~~~
Benchmark | time ---|--- 1 | 54.084 us 54.232 us 54.383 us 2 | 191.25 ns 191.64 ns 192.26 ns 3 | 190.73 ns 190.86 ns 191.03 ns
~~~rust
let mut wordlist: Vec
~~~
running 6 tests test tests::defaultxpgreturnsfourwords ... ignored test tests::xpgcanreturnfivewords ... ignored test tests::xpgcanreturnfourwords ... ignored test tests::xpgcanreturnoneword ... ignored test tests::xpgcanreturnthreewords ... ignored test tests::xpgcannotreturnzerowords ... ignored
test result: ok. 0 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Benchmarking xpg Benchmarking xpg: Warming up for 3.0000 s Benchmarking xpg: Collecting 100 samples in estimated 5.1942 s (96k iterations) Benchmarking xpg: Analyzing xpg time: [54.084 us 54.232 us 54.383 us] Found 18 outliers among 100 measurements (18.00%) 1 (1.00%) low severe 16 (16.00%) high mild 1 (1.00%) high severe
~~~
~~~rust
let p: Vec<&str> = WORDLIST.choosemultiple(&mut threadrng(), words)
.cloned().collect::
~~~
running 6 tests test tests::defaultxpgreturnsfourwords ... ignored test tests::xpgcanreturnfivewords ... ignored test tests::xpgcanreturnfourwords ... ignored test tests::xpgcanreturnoneword ... ignored test tests::xpgcanreturnthreewords ... ignored test tests::xpgcannotreturnzerowords ... ignored
test result: ok. 0 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Benchmarking xpg Benchmarking xpg: Warming up for 3.0000 s Benchmarking xpg: Collecting 100 samples in estimated 5.0002 s (24M iterations) Benchmarking xpg: Analyzing xpg time: [191.25 ns 191.64 ns 192.26 ns] change: [-99.649% -99.648% -99.646%] (p = 0.00 < 0.05) Performance has improved. Found 6 outliers among 100 measurements (6.00%) 2 (2.00%) high mild 4 (4.00%) high severe
~~~
~~~rust
WORDLIST.choosemultiple(&mut threadrng(), words)
.cloned().collect::
~~~
running 6 tests test tests::defaultxpgreturnsfourwords ... ignored test tests::xpgcanreturnfivewords ... ignored test tests::xpgcanreturnfourwords ... ignored test tests::xpgcanreturnoneword ... ignored test tests::xpgcanreturnthreewords ... ignored test tests::xpgcannotreturnzerowords ... ignored
test result: ok. 0 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Benchmarking xpg Benchmarking xpg: Warming up for 3.0000 s Benchmarking xpg: Collecting 100 samples in estimated 5.0003 s (25M iterations) Benchmarking xpg: Analyzing xpg time: [190.73 ns 190.86 ns 191.03 ns] change: [-0.5139% -0.1940% +0.1608%] (p = 0.27 > 0.05) No change in performance detected. Found 8 outliers among 100 measurements (8.00%) 2 (2.00%) high mild 6 (6.00%) high severe
~~~