Creating a random secret key in Raku

2 minute read

This post might seem a bit silly, because I’ve already posted this tip on Twitter about a year ago. Nevertheless, I needed exactly this piece of information recently and it took me a while to find it again. Once I realised it was on Twitter, I thought it’s probably a good idea to mention the tip on my own site as well. Also, I’m not restricted to 140 characters here, so I can be a bit more explicit :smiley:.

So, the problem is that I needed to create a 50-character random string. In my particular case this was to set the value of the SECRET_KEY variable in a Django configuration at work. Of course, it’s possible to create the required key using Python from within Django; the standard solution looks like this:

$ python manage.py shell --settings=config.settings.dev
Python 3.7.3 (default, Apr  3 2019, 05:39:12)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.management.utils import get_random_secret_key
>>> get_random_secret_key()
'i7t2d5y80ty9c5!bs(onmk-b+)$=xcgi+-z&3mgupsqw+_85s_'

However, being a Perl/Raku developer at heart, this seemed to be one hell of a lot of typing and much more complicated than such a simple task should be.

Now, I know that with Raku you can pick a number of random elements from a list with the pick routine.1

Therefore, the solution to my problem using the Raku REPL was:

$ raku
To exit type 'exit' or '^D'
> ("0" .. "z").pick(50).join.say
unFTze3SV1jAh50J[R:MarPWdk\4tm2`qfCHZ]?OpysKbo6UG7

Put simply, this says to take the list of characters between 0 and z2, select 50 items at random, join the resulting list together, and then say the answer.3 Which is just another way of saying “give me a string of 50 random characters”. Easy.

This also makes a really simple one-liner:

$ raku -e '("0" .. "z").pick(50).join.say'
u[zarviW;bsh?:y8oclEGFA^xY_N3<0VpZCJHPLdj5UXkK`w19

What a beautifully elegant language!

If you really want the single quotes surrounding the generated string, then something like this should suffice:

$ raku -e "say Q (') ~ ('0' ..  'z').pick(50).join ~ Q (')"

Now, I’m sure there must be some way to write the Python code as a one-liner, but I’m also sure that such frivolity would be frowned upon by Python programmers as being “unpythonic”. Oh well.

  1. If that seems like a Captain Obvious comment, that’s good, because such things should be obvious. Easy things should be easy; hard things should be possible. Note that this is a language designed by a linguist. 

  2. The list from 0 to z contains all digits, upper and lower case ASCII letters as well as various special characters, i.e.: 0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz

  3. Strictly speaking, the say isn’t necessary, because the REPL “says” the output by default. The say is, however, necessary in a one-liner. 

Categories:

Updated:

Comments