0

For the password entry field of an email client that I am making, I thought that it would be cool to have the password show random characters. Since I don't want to write down a dictionary of all ascii characters, I was wondering if there is a module which I could import to get it. My idea of the code looks like this:

import random
import char_set #All ascii characters

def random_char():

    char_select = random.randrange(len(char_set))

    char_choice = char_set[char_select]

    return char_choice

NOTE: This must be cross-platform as I run on Mac OSX, Windows, and Debian (Raspberry Pi).

xxmbabanexx
  • 8,256
  • 16
  • 40
  • 60
  • 1
    it's in the `string` module. – mgilson Apr 19 '13 at 18:06
  • @mgilson: I don't think there's any such collection in `string`. There's `ascii_letters`, but that's just letters. And `printable`, but that includes things like `\t` and ` `. – abarnert Apr 19 '13 at 18:09
  • By definition, ASCII (or any other complete 7-bit character set) is just `chr(x) for x in range(128)`. – abarnert Apr 19 '13 at 18:13
  • As a side note: Instead of using `randrange(len())` to get an index, just use `random.choice(char_set)`. – abarnert Apr 19 '13 at 18:14
  • No module, but code is [short](http://stackoverflow.com/questions/2257441/python-random-string-generation-with-upper-case-letters-and-digits) – Alvin K. Apr 19 '13 at 18:31

2 Answers2

5

The whole ASCII set:

In [22]: "".join(chr(x) for x in range(128))
Out[22]: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f'

If you want the printable ascii characters:

In [9]: "".join(chr(x) for x in range(32,127))
Out[9]: ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'

or if you only want the alphabets:

In [10]: import string

In [11]: string.ascii_letters
Out[11]: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

string.printable is also an option, it contains 5 extra charcters that are not in the range(32,127):

In [39]: s1=set(x for x in string.printable)

In [40]: s2=set(chr(x) for x in range(32,127))

In [41]: s1-s2
Out[41]: set(['\t', '\x0b', '\n', '\r', '\x0c'])

ASCII Table

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • The whole ascii set is `range(128)`, not `range(32,127)`. And the "printable characters" include (among other things) `\n` if they include ` `. – abarnert Apr 19 '13 at 18:10
  • @abarnert I know, but I thought may be OP is looking only for the printable characters. – Ashwini Chaudhary Apr 19 '13 at 18:19
  • @abarnert "printable characters" usually means "not [control characters](http://en.wikipedia.org/wiki/ASCII#ASCII_control_characters)", and "control characters" are almost always defined as 0-31,127 – Aya Apr 19 '13 at 18:22
  • @Aya: Python has a specific definition for "printable", which is what `string.printable` is there for. So it's a bad idea to reuse the same name to mean something different. – abarnert Apr 19 '13 at 18:44
  • @abarnert Indeed. It was probably a bad idea for Python to reuse the name "printable" in the way it does, considering everyone else has been using it to mean "ASCII 32-126" since the 1960s. To avoid confusion, it's probably better to always refer to Python's definition as `string.printable`. – Aya Apr 19 '13 at 19:05
  • Actually, an awful lot of people refer to it to mean "ASCII 33-126"—again. In many contexts, spaces aren't printable (they don't cause the print head to smack the paper); and in many contexts where spaces count (because they do move the print head), so do, e.g., tabs (for the same reason). Which is why Python defines `string.printable` the way it does. – abarnert Apr 19 '13 at 19:14
  • 2
    @abarnert I'm sure many people have their own definition, but ASCII "printable characters" was most recently defined in the ANSI X3.4-1986 standard to mean "ASCII 32-126", and I suspect 9 out of 10 programmers would give you the same definition if asked, if only because [that's what Wikipedia says](http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters). ;-) – Aya Apr 19 '13 at 19:36
3

The string module includes a number of constants you can use: string.letters, string.numbers, string.punctuation, etc. string.printable seems to be largely what you want.

If you don't want to use a module, just do printable_chars = "".join(chr(c) for c in xrange(33, 127)) (this excludes space and rubout intentionally).

kindall
  • 178,883
  • 35
  • 278
  • 309