initial commit
This commit is contained in:
83
src/passphrase.nim
Normal file
83
src/passphrase.nim
Normal file
@ -0,0 +1,83 @@
|
||||
import std/[os, strutils]
|
||||
import nimcrypto/sysrand
|
||||
|
||||
|
||||
type Dictionary = object
|
||||
words: string
|
||||
offsets: seq[uint32]
|
||||
|
||||
|
||||
proc `[]`(d: Dictionary, i: Natural): string =
|
||||
# last word has no following start index, so we have to fake it
|
||||
# also strings are indexed with ints
|
||||
let slice = if i == d.offsets.high:
|
||||
d.offsets[i].int .. d.words.high
|
||||
else:
|
||||
d.offsets[i].int ..< d.offsets[i + 1].int
|
||||
|
||||
result = d.words[slice]
|
||||
|
||||
|
||||
proc len(d: Dictionary): int =
|
||||
result = d.offsets.len
|
||||
|
||||
|
||||
proc loadWords(): Dictionary =
|
||||
for word in staticRead("dictionary.txt").strip().splitLines():
|
||||
let startIdx = result.words.len.uint32
|
||||
result.offsets.add(startIdx)
|
||||
result.words.add(word)
|
||||
|
||||
|
||||
const dict = loadWords()
|
||||
|
||||
|
||||
proc genPassphrase(length, dictSize: int): string =
|
||||
if dictSize < 100 or dictSize > dict.len:
|
||||
quit("Dictionary size must be between 100 and " & $dict.len, 1)
|
||||
|
||||
var rands = newSeq[uint64](length)
|
||||
discard randomBytes(rands)
|
||||
|
||||
var words: seq[string]
|
||||
for r in rands:
|
||||
let i = r mod dictSize.uint64
|
||||
words.add(dict[i])
|
||||
result = words.join(" ")
|
||||
|
||||
|
||||
const help = """Usage:
|
||||
passphrase [LENGTH] [DICTSIZE]
|
||||
|
||||
Defaults to length of 4 and dictionary size of 25,000."""
|
||||
|
||||
proc parseInput(): (int, int) =
|
||||
let params = commandLineParams()
|
||||
if "-h" in params or "--help" in params:
|
||||
echo help
|
||||
quit(0)
|
||||
|
||||
var
|
||||
length = 4
|
||||
dictSize = 25_000
|
||||
|
||||
if params.len > 0:
|
||||
try:
|
||||
length = parseInt(params[0])
|
||||
except ValueError:
|
||||
quit(params[0] & " is not a valid passphrase length.", 1)
|
||||
|
||||
if params.len > 1:
|
||||
try:
|
||||
dictSize = parseInt(params[1])
|
||||
if dictSize < 100 or dictSize > dict.len:
|
||||
quit("Dictionary size must be between 100 and " & $dict.len, 1)
|
||||
except ValueError:
|
||||
quit(params[1] & " is not a valid dictionary size.", 1)
|
||||
|
||||
result = (length, dictSize)
|
||||
|
||||
|
||||
when isMainModule:
|
||||
let (length, dictSize) = parseInput()
|
||||
echo genPassphrase(length, dictSize)
|
Reference in New Issue
Block a user