passphrase/src/dictionary.nim

63 lines
1.3 KiB
Nim

import std/strutils
import zippy
type
Dictionary* = object
words: string
width: uint32
proc `[]`*(d: Dictionary, i: Natural): string =
let start = i.uint32 * d.width
d.words[start ..< start + d.width]
proc len*(d: Dictionary): int =
result = d.words.len div d.width.int
proc addU32(s: var string, i: uint32) =
for offset in 0..3:
let b = cast[char](i shr (offset * 8))
s.add(b)
proc getU32(s: string): uint32 =
for offset in 0..3:
result = result or (cast[uint32](s[offset]) shl (offset * 8))
proc pack*(d: Dictionary): string =
var data: string
data.addU32(d.width)
data.add(d.words)
data.compress(dataFormat = dfGzip)
proc unpack*(p: string): Dictionary =
let data = p.uncompress(dataFormat = dfGzip)
result.width = data.getU32()
result.words = data[4..^1]
proc loadWords*(path: string): Dictionary =
result.width = 25
for word in readFile(path).strip().splitLines():
if word.len > 25:
continue
result.words.add(word)
for _ in 0 ..< (25 - word.len):
result.words.add(' ')
when isMainModule:
import std/os
echo "Loading words..."
let dictionary = loadWords(paramStr(1))
echo "Packing dictionary..."
let packed = dictionary.pack()
writeFile(paramStr(2), packed)
echo "Dictionary packed."