#!/usr/bin/env sh
# -*- wisp -*-
exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples safepassword) main)' -s "$0" "$@"
; !#
;; Create safe passwords, usable on US and German keyboards without problems
define-module : examples safepassword
. #:export : password
import
only (srfi srfi-27) random-source-make-integers
. make-random-source random-source-randomize!
only (srfi srfi-1) second
define random-source : make-random-source
random-source-randomize! random-source
define random-integer
random-source-make-integers random-source
define : randomletter letters
string-ref letters
random-integer
string-length letters
define : password length
let
: quertysafeletters "0123456789ABCDEFGHJKLMNPQRSTUVWXabcdefghijkmnopqrstuvwx"
;; that’s newbase60 without yz_
;; means 5.78 bits entropy per letter.
delimiters ",.!?-+"
;; that’s 2.5 bits entropy per delimiter
let fill
: letters '()
remaining length
if : zero? remaining
reverse-list->string letters
fill
cons : randomletter quertysafeletters
if : and (not (= length remaining)) : zero? : modulo remaining 4
cons : randomletter delimiters
. letters
. letters
- remaining 1
define : main args
let
:
len
if : = 2 : length args
string->number : second args
. 16
display : password len
newline