Generate EFF diceware passwords with Python

How does the reference system of the Majjhima Nikaya work?

We have a love-hate relationship

What (else) happened July 1st 1858 in London?

Will adding a BY-SA image to a blog post make the entire post BY-SA?

Two-sided logarithm inequality

Query about absorption line spectra

How do you respond to a colleague from another team when they're wrongly expecting that you'll help them?

How can "mimic phobia" be cured or prevented?

If a character with the Alert feat rolls a crit fail on their Perception check, are they surprised?

Have I saved too much for retirement so far?

MAXDOP Settings for SQL Server 2014

When quoting, must I also copy hyphens used to divide words that continue on the next line?

Can not upgrade Kali,not enough space in /var/cache/apt/archives

Can I use my Chinese passport to enter China after I acquired another citizenship?

Why does Async/Await work properly when the loop is inside the async function and not the other way around?

Is it improper etiquette to ask your opponent what his/her rating is before the game?

Fuse symbol on toroidal transformer

A Permanent Norse Presence in America

Could the E-bike drivetrain wear down till needing replacement after 400 km?

Is there a conventional notation or name for the slip angle?

Filling the middle of a torus in Tikz

A social experiment. What is the worst that can happen?

Can a significant change in incentives void an employment contract?

Greco-Roman egalitarianism



Generate EFF diceware passwords with Python














0












$begingroup$


I wanted to write a commandline scipt to generate diceware passwords based on the EFF diceware list.



The script (diceware_password.py) can be found below. It was originally developed for Python 2, but I want it to be compatible with Python 3 as well (both versions have been tested on my machine).
Running it with no arguments will generate a 6 word password as recommended by the EFF. Additionally, you may also input dice throws made in the "real world".
Note: You need to download the EFF's large wordlist for the script to work. It assumes the default filename, but you can pass other filenames using the --wordlist flag.



Any feedback is very welcome, especially on the clarity of the code, as well as Python 2/3 compatibility best practices. Thanks in advance!



#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function

import random
import codecs
import argparse

import six.moves


def large_wordlist_from_file(fname, sep="t"):
"""Read an EFF compatible large wordlist from file"""
word_dict =
with codecs.open(fname, encoding="utf-8", mode="rb") as file_:
while True:
line = file_.readline()
if line:
key, word = line.strip().split(sep)
word_dict[tuple(int(i) for i in key)] = word
else:
break
return word_dict


def roll_dices(nrolls, ndices=5):
"""Rolls a number of dices (default: 5) n times"""
rng = random.SystemRandom()
return tuple(
tuple(rng.randrange(1, 7) for _ in six.moves.range(ndices)) for _ in six.moves.range(nrolls)
)


def validate_dice_rolls(roll_sequences):
"""Validate dice sequences from user input"""
rolls = []
for roll_sequence in roll_sequences:
roll = []
for throw in roll_sequence:
if not (1 <= int(throw) <= 6):
raise ValueError("Each throw must be between 1 and 6.")
roll.append(int(throw))
if len(roll) != 5:
raise ValueError("Each roll sequence has to be of length 5 "
"to work with the EFF wordlist!")
rolls.append(tuple(roll))
return rolls

def get_interactive_dice_rolls():
"""Enter your dice throws on the command line"""
rolls = []
while True:
user_input = six.moves.input("Please enter your dice sequences: ")
roll_sequence = user_input.strip().split(" ")
try:
rolls = validate_dice_rolls(roll_sequence)
break
except ValueError as ex:
print("Failed to parse your input for the following reason: "+ex.message)
user_input = six.moves.input("Do you want to try again? (y/n) ")
user_input = user_input.strip().lower()
if user_input.startswith("n"):
break
return rolls


def main():
"""Commandline script to generate diceware passwords"""
parser = argparse.ArgumentParser(
description="Generate diceware passwords with N words. "
"EFF recommendation is N >= 6."
)
parser.add_argument(
"n", metavar="N", type=int, nargs="?", default=6,
help="number of diceware words (default: 6)",
)
parser.add_argument(
"--real-dice", type=str, nargs="*", metavar="DICE_SEQUENCE",
help="instead of using PRNG, use your given dice throws. "
"Please group them in N DICE_SEQUENCEs of length 5 seperated "
"by a space"
)
parser.add_argument(
"--wordlist", type=str, nargs="?", default="eff_large_wordlist.txt",
help="The diceware wordlist to use. This script assumes the list to "
"contain one word per line where each word is preceeded by its "
"'dice' index. Index and word are separated by a single tab. "
"(default: "eff_large_wordlist.txt")"
)
parser.add_argument(
"--interactive", action="store_true", default=False,
help="Interactive mode allows you to enter your dice sequences via "
"command prompt in order to avoid traces in your bash history"
)
args = parser.parse_args()

words = large_wordlist_from_file(args.wordlist, "t")
rolls = []
if args.real_dice is not None:
rolls = validate_dice_rolls(args.real_dice)
elif args.interactive:
rolls = get_interactive_dice_rolls()
else:
rolls = roll_dices(args.n, 5)

if rolls:
# print the result
try:
print(" ".join(words[roll] for roll in rolls))
except KeyError:
print(list(words.keys()))


if __name__ == "__main__":
main()









share









$endgroup$
















    0












    $begingroup$


    I wanted to write a commandline scipt to generate diceware passwords based on the EFF diceware list.



    The script (diceware_password.py) can be found below. It was originally developed for Python 2, but I want it to be compatible with Python 3 as well (both versions have been tested on my machine).
    Running it with no arguments will generate a 6 word password as recommended by the EFF. Additionally, you may also input dice throws made in the "real world".
    Note: You need to download the EFF's large wordlist for the script to work. It assumes the default filename, but you can pass other filenames using the --wordlist flag.



    Any feedback is very welcome, especially on the clarity of the code, as well as Python 2/3 compatibility best practices. Thanks in advance!



    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    from __future__ import print_function

    import random
    import codecs
    import argparse

    import six.moves


    def large_wordlist_from_file(fname, sep="t"):
    """Read an EFF compatible large wordlist from file"""
    word_dict =
    with codecs.open(fname, encoding="utf-8", mode="rb") as file_:
    while True:
    line = file_.readline()
    if line:
    key, word = line.strip().split(sep)
    word_dict[tuple(int(i) for i in key)] = word
    else:
    break
    return word_dict


    def roll_dices(nrolls, ndices=5):
    """Rolls a number of dices (default: 5) n times"""
    rng = random.SystemRandom()
    return tuple(
    tuple(rng.randrange(1, 7) for _ in six.moves.range(ndices)) for _ in six.moves.range(nrolls)
    )


    def validate_dice_rolls(roll_sequences):
    """Validate dice sequences from user input"""
    rolls = []
    for roll_sequence in roll_sequences:
    roll = []
    for throw in roll_sequence:
    if not (1 <= int(throw) <= 6):
    raise ValueError("Each throw must be between 1 and 6.")
    roll.append(int(throw))
    if len(roll) != 5:
    raise ValueError("Each roll sequence has to be of length 5 "
    "to work with the EFF wordlist!")
    rolls.append(tuple(roll))
    return rolls

    def get_interactive_dice_rolls():
    """Enter your dice throws on the command line"""
    rolls = []
    while True:
    user_input = six.moves.input("Please enter your dice sequences: ")
    roll_sequence = user_input.strip().split(" ")
    try:
    rolls = validate_dice_rolls(roll_sequence)
    break
    except ValueError as ex:
    print("Failed to parse your input for the following reason: "+ex.message)
    user_input = six.moves.input("Do you want to try again? (y/n) ")
    user_input = user_input.strip().lower()
    if user_input.startswith("n"):
    break
    return rolls


    def main():
    """Commandline script to generate diceware passwords"""
    parser = argparse.ArgumentParser(
    description="Generate diceware passwords with N words. "
    "EFF recommendation is N >= 6."
    )
    parser.add_argument(
    "n", metavar="N", type=int, nargs="?", default=6,
    help="number of diceware words (default: 6)",
    )
    parser.add_argument(
    "--real-dice", type=str, nargs="*", metavar="DICE_SEQUENCE",
    help="instead of using PRNG, use your given dice throws. "
    "Please group them in N DICE_SEQUENCEs of length 5 seperated "
    "by a space"
    )
    parser.add_argument(
    "--wordlist", type=str, nargs="?", default="eff_large_wordlist.txt",
    help="The diceware wordlist to use. This script assumes the list to "
    "contain one word per line where each word is preceeded by its "
    "'dice' index. Index and word are separated by a single tab. "
    "(default: "eff_large_wordlist.txt")"
    )
    parser.add_argument(
    "--interactive", action="store_true", default=False,
    help="Interactive mode allows you to enter your dice sequences via "
    "command prompt in order to avoid traces in your bash history"
    )
    args = parser.parse_args()

    words = large_wordlist_from_file(args.wordlist, "t")
    rolls = []
    if args.real_dice is not None:
    rolls = validate_dice_rolls(args.real_dice)
    elif args.interactive:
    rolls = get_interactive_dice_rolls()
    else:
    rolls = roll_dices(args.n, 5)

    if rolls:
    # print the result
    try:
    print(" ".join(words[roll] for roll in rolls))
    except KeyError:
    print(list(words.keys()))


    if __name__ == "__main__":
    main()









    share









    $endgroup$














      0












      0








      0





      $begingroup$


      I wanted to write a commandline scipt to generate diceware passwords based on the EFF diceware list.



      The script (diceware_password.py) can be found below. It was originally developed for Python 2, but I want it to be compatible with Python 3 as well (both versions have been tested on my machine).
      Running it with no arguments will generate a 6 word password as recommended by the EFF. Additionally, you may also input dice throws made in the "real world".
      Note: You need to download the EFF's large wordlist for the script to work. It assumes the default filename, but you can pass other filenames using the --wordlist flag.



      Any feedback is very welcome, especially on the clarity of the code, as well as Python 2/3 compatibility best practices. Thanks in advance!



      #!/usr/bin/env python
      # -*- coding: utf-8 -*-
      from __future__ import print_function

      import random
      import codecs
      import argparse

      import six.moves


      def large_wordlist_from_file(fname, sep="t"):
      """Read an EFF compatible large wordlist from file"""
      word_dict =
      with codecs.open(fname, encoding="utf-8", mode="rb") as file_:
      while True:
      line = file_.readline()
      if line:
      key, word = line.strip().split(sep)
      word_dict[tuple(int(i) for i in key)] = word
      else:
      break
      return word_dict


      def roll_dices(nrolls, ndices=5):
      """Rolls a number of dices (default: 5) n times"""
      rng = random.SystemRandom()
      return tuple(
      tuple(rng.randrange(1, 7) for _ in six.moves.range(ndices)) for _ in six.moves.range(nrolls)
      )


      def validate_dice_rolls(roll_sequences):
      """Validate dice sequences from user input"""
      rolls = []
      for roll_sequence in roll_sequences:
      roll = []
      for throw in roll_sequence:
      if not (1 <= int(throw) <= 6):
      raise ValueError("Each throw must be between 1 and 6.")
      roll.append(int(throw))
      if len(roll) != 5:
      raise ValueError("Each roll sequence has to be of length 5 "
      "to work with the EFF wordlist!")
      rolls.append(tuple(roll))
      return rolls

      def get_interactive_dice_rolls():
      """Enter your dice throws on the command line"""
      rolls = []
      while True:
      user_input = six.moves.input("Please enter your dice sequences: ")
      roll_sequence = user_input.strip().split(" ")
      try:
      rolls = validate_dice_rolls(roll_sequence)
      break
      except ValueError as ex:
      print("Failed to parse your input for the following reason: "+ex.message)
      user_input = six.moves.input("Do you want to try again? (y/n) ")
      user_input = user_input.strip().lower()
      if user_input.startswith("n"):
      break
      return rolls


      def main():
      """Commandline script to generate diceware passwords"""
      parser = argparse.ArgumentParser(
      description="Generate diceware passwords with N words. "
      "EFF recommendation is N >= 6."
      )
      parser.add_argument(
      "n", metavar="N", type=int, nargs="?", default=6,
      help="number of diceware words (default: 6)",
      )
      parser.add_argument(
      "--real-dice", type=str, nargs="*", metavar="DICE_SEQUENCE",
      help="instead of using PRNG, use your given dice throws. "
      "Please group them in N DICE_SEQUENCEs of length 5 seperated "
      "by a space"
      )
      parser.add_argument(
      "--wordlist", type=str, nargs="?", default="eff_large_wordlist.txt",
      help="The diceware wordlist to use. This script assumes the list to "
      "contain one word per line where each word is preceeded by its "
      "'dice' index. Index and word are separated by a single tab. "
      "(default: "eff_large_wordlist.txt")"
      )
      parser.add_argument(
      "--interactive", action="store_true", default=False,
      help="Interactive mode allows you to enter your dice sequences via "
      "command prompt in order to avoid traces in your bash history"
      )
      args = parser.parse_args()

      words = large_wordlist_from_file(args.wordlist, "t")
      rolls = []
      if args.real_dice is not None:
      rolls = validate_dice_rolls(args.real_dice)
      elif args.interactive:
      rolls = get_interactive_dice_rolls()
      else:
      rolls = roll_dices(args.n, 5)

      if rolls:
      # print the result
      try:
      print(" ".join(words[roll] for roll in rolls))
      except KeyError:
      print(list(words.keys()))


      if __name__ == "__main__":
      main()









      share









      $endgroup$




      I wanted to write a commandline scipt to generate diceware passwords based on the EFF diceware list.



      The script (diceware_password.py) can be found below. It was originally developed for Python 2, but I want it to be compatible with Python 3 as well (both versions have been tested on my machine).
      Running it with no arguments will generate a 6 word password as recommended by the EFF. Additionally, you may also input dice throws made in the "real world".
      Note: You need to download the EFF's large wordlist for the script to work. It assumes the default filename, but you can pass other filenames using the --wordlist flag.



      Any feedback is very welcome, especially on the clarity of the code, as well as Python 2/3 compatibility best practices. Thanks in advance!



      #!/usr/bin/env python
      # -*- coding: utf-8 -*-
      from __future__ import print_function

      import random
      import codecs
      import argparse

      import six.moves


      def large_wordlist_from_file(fname, sep="t"):
      """Read an EFF compatible large wordlist from file"""
      word_dict =
      with codecs.open(fname, encoding="utf-8", mode="rb") as file_:
      while True:
      line = file_.readline()
      if line:
      key, word = line.strip().split(sep)
      word_dict[tuple(int(i) for i in key)] = word
      else:
      break
      return word_dict


      def roll_dices(nrolls, ndices=5):
      """Rolls a number of dices (default: 5) n times"""
      rng = random.SystemRandom()
      return tuple(
      tuple(rng.randrange(1, 7) for _ in six.moves.range(ndices)) for _ in six.moves.range(nrolls)
      )


      def validate_dice_rolls(roll_sequences):
      """Validate dice sequences from user input"""
      rolls = []
      for roll_sequence in roll_sequences:
      roll = []
      for throw in roll_sequence:
      if not (1 <= int(throw) <= 6):
      raise ValueError("Each throw must be between 1 and 6.")
      roll.append(int(throw))
      if len(roll) != 5:
      raise ValueError("Each roll sequence has to be of length 5 "
      "to work with the EFF wordlist!")
      rolls.append(tuple(roll))
      return rolls

      def get_interactive_dice_rolls():
      """Enter your dice throws on the command line"""
      rolls = []
      while True:
      user_input = six.moves.input("Please enter your dice sequences: ")
      roll_sequence = user_input.strip().split(" ")
      try:
      rolls = validate_dice_rolls(roll_sequence)
      break
      except ValueError as ex:
      print("Failed to parse your input for the following reason: "+ex.message)
      user_input = six.moves.input("Do you want to try again? (y/n) ")
      user_input = user_input.strip().lower()
      if user_input.startswith("n"):
      break
      return rolls


      def main():
      """Commandline script to generate diceware passwords"""
      parser = argparse.ArgumentParser(
      description="Generate diceware passwords with N words. "
      "EFF recommendation is N >= 6."
      )
      parser.add_argument(
      "n", metavar="N", type=int, nargs="?", default=6,
      help="number of diceware words (default: 6)",
      )
      parser.add_argument(
      "--real-dice", type=str, nargs="*", metavar="DICE_SEQUENCE",
      help="instead of using PRNG, use your given dice throws. "
      "Please group them in N DICE_SEQUENCEs of length 5 seperated "
      "by a space"
      )
      parser.add_argument(
      "--wordlist", type=str, nargs="?", default="eff_large_wordlist.txt",
      help="The diceware wordlist to use. This script assumes the list to "
      "contain one word per line where each word is preceeded by its "
      "'dice' index. Index and word are separated by a single tab. "
      "(default: "eff_large_wordlist.txt")"
      )
      parser.add_argument(
      "--interactive", action="store_true", default=False,
      help="Interactive mode allows you to enter your dice sequences via "
      "command prompt in order to avoid traces in your bash history"
      )
      args = parser.parse_args()

      words = large_wordlist_from_file(args.wordlist, "t")
      rolls = []
      if args.real_dice is not None:
      rolls = validate_dice_rolls(args.real_dice)
      elif args.interactive:
      rolls = get_interactive_dice_rolls()
      else:
      rolls = roll_dices(args.n, 5)

      if rolls:
      # print the result
      try:
      print(" ".join(words[roll] for roll in rolls))
      except KeyError:
      print(list(words.keys()))


      if __name__ == "__main__":
      main()







      python python-3.x python-2.x





      share












      share










      share



      share










      asked 7 mins ago









      AlexAlex

      593211




      593211




















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216128%2fgenerate-eff-diceware-passwords-with-python%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216128%2fgenerate-eff-diceware-passwords-with-python%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

          格濟夫卡 參考資料 导航菜单51°3′40″N 34°2′21″E / 51.06111°N 34.03917°E / 51.06111; 34.03917ГезівкаПогода в селі 编辑或修订