103 lines
2.7 KiB
Python
Executable File
103 lines
2.7 KiB
Python
Executable File
#!/usr/bin/python3
|
|
from math import *
|
|
import random
|
|
import string
|
|
import sys
|
|
import os
|
|
|
|
from common import *
|
|
from longrandom import LongRandom
|
|
from worddict import words
|
|
|
|
print("Content-Type: text/html")
|
|
print()
|
|
|
|
qs = os.environ.get('QUERY_STRING', None)
|
|
if not qs:
|
|
minlen = 1
|
|
maxlen = 8
|
|
numlen = 2
|
|
wordcount = 3
|
|
extra_symbols = ''
|
|
randcaps = 'first'
|
|
else:
|
|
form = cgi.FieldStorage()
|
|
wordcount = form_get(form, 'wordcount', 3, int)
|
|
minlen = form_get(form, 'minlen', 2, int)
|
|
maxlen = form_get(form, 'maxlen', 8, int)
|
|
numlen = form_get(form, 'numlen', 2, int)
|
|
randcaps = form_get(form, 'randcaps', 'first', str)
|
|
|
|
dumpfile('header.html', {'type':'Passphrase'})
|
|
dict = EvalDict(vars())
|
|
here = os.path.dirname(__file__)
|
|
form_path = os.path.join(here, 'ppform.html')
|
|
with open(form_path, encoding="utf-8") as f:
|
|
sys.stdout.write(f.read() % dict)
|
|
|
|
usewords = [ ]
|
|
totalen = 0
|
|
for i in range(minlen, maxlen+1):
|
|
totalen += len(words[i]) * i
|
|
usewords.extend(words[i])
|
|
|
|
log_2 = log(2)
|
|
wordbits = log(len(usewords)) / log_2
|
|
medlen = len(usewords[len(usewords)//2])
|
|
avglen = totalen / len(usewords)
|
|
if randcaps == 'first':
|
|
capbits = 1
|
|
capmult = 2
|
|
elif randcaps == 'one':
|
|
# Use estimate based on average word length
|
|
capbits = log(avglen+1) / log_2
|
|
capmult = avglen+1
|
|
elif randcaps == 'all':
|
|
# One bit per average word length
|
|
capbits = avglen
|
|
capmult = 2**avglen
|
|
else:
|
|
capbits = 0
|
|
capmult = 1
|
|
numbits = log(10) * numlen / log_2
|
|
numfmt = '{{:0{}}}'.format(numlen)
|
|
passbits = (wordbits + capbits) * wordcount + numbits * ((wordcount - 1) or 1)
|
|
|
|
table_start()
|
|
row('Word count', commafy(len(usewords)))
|
|
row('Average word length', '%.2f' % avglen)
|
|
row('Bits per word', '%.2f' % wordbits)
|
|
row('Bits per number', '%.2f' % numbits)
|
|
row('Bits for capitalization', '%.2f' % (capbits * wordcount))
|
|
row('Effective passphrase bits', int(passbits))
|
|
row('Total possible combinations',
|
|
commafy(len(usewords)**wordcount * (10**numlen)**((wordcount-1) or 1) * capmult**wordcount))
|
|
table_end()
|
|
|
|
randval = LongRandom()
|
|
|
|
table_start()
|
|
print("<tr><th>Passphrase</th></tr>")
|
|
for i in range(10):
|
|
passphrase = ''
|
|
for j in range(wordcount):
|
|
word = usewords[randval.get(len(usewords))]
|
|
if randcaps == 'first':
|
|
if randval.get(2):
|
|
word = word[0].upper() + word[1:]
|
|
elif randcaps == 'one':
|
|
k = randval.get(len(word)+1)
|
|
if k < len(word):
|
|
word = word[:k] + word[k].upper() + word[k+1:]
|
|
elif randcaps == 'all':
|
|
word = ''.join([ randval.get(2) and ch.upper() or ch.lower()
|
|
for ch in word ])
|
|
passphrase += word
|
|
if numlen > 0 and (j < wordcount-1 or wordcount == 1):
|
|
passphrase += numfmt.format(randval.get(10 ** numlen))
|
|
|
|
print("<tr><td><tt>%s</tt></td></tr>" % escape(passphrase))
|
|
|
|
table_end()
|
|
dumpfile('footer.html')
|