How about (NOT SECURE YET, IT NEEDS MORE ENTROPY):
from nltk.corpus import wordnet as wn
all_animals = set()
def add_to_set(animal):
all_animals.add(animal.name.split('.')[0].replace('_',' '))
for child in animal.hyponyms():
add_to_set(child)
add_to_set(wn.synset('animal.n.01'))
all_animals = list(all_animals)
actions = ['ate','chased','killed','fought','kissed',
'talked to','hated','loved','ambushed','fled'] # can add more
def make_password():
import random
random = random.SystemRandom() # is this secure?
choice = random.choice
return 'the %s %s the %s'%(choice(all_animals), choice(actions), choice(all_animals))
If you pruned out 90% of the animals (i.e. the obscure, hard to spell, or scientific names), this is still about 20 bits. And the passwords are kind of memorable (I've gotten such gems as "the dodo chased the guppy" or "the tigress killed the king charles spanial").
You could also add a humorous adjective ("rabid", "talking", "magic", "invisible", "evil" ...) or adverb ("roughly", "quickly", "quietly", "secretly" ...).
Completely random strings of words can be hard for me to remember, but something like, "the {adjective1} {animal1} {verb} the {ajective2} {verb2}" would be much easier for me to remember because the words relate to each other ways I already understand.
I expect we can get some fairly high entropy from just simple schemes like this.
However, the length of the password can be a real pain if you have to type it often, even once a day.
You could get about 8 bits per animal, and 5 bits per hand-written verb / adjective / place (32 choices per category). So that's about 7-10 words you need in the frame.
You could get decent entropy with: the {adj} {adj} {animal} {verbed} the {adj} {adj} {animal} from in {place}. That's 5+5+8+5+5+8+5 = 41 bits.
This is truly awesome. You could easily use a more complicated grammar, but it might get tricky to generate a password with a specified amount of entropy.
You could also add a humorous adjective ("rabid", "talking", "magic", "invisible", "evil" ...) or adverb ("roughly", "quickly", "quietly", "secretly" ...).
You could also add a place name.