Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
A tiny password generator script
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
Goverp
Advocate
Advocate


Joined: 07 Mar 2007
Posts: 2179

PostPosted: Sat Sep 07, 2024 6:45 pm    Post subject: A tiny password generator script Reply with quote

This script one-liner is a shorter version of one that appears on the Internet, using /dev/urandom:

Code:
dd if=/dev/urandom bs=12 count=1 status=none | base64


The result is a 16-byte totally unmemorable ASCII string complete (usually) with special characters, upper/lower case and numbers, so it's useful if you store the results in a password vault, but not much otherwise! Sometimes it generates unacceptable passwords - something that doesn't have special characters or numbers or perhaps special characters or whatever, so try again!

(The longer Internet version is along the lines of
Code:
dd if=/dev/urandom count=1 2> /dev/null | uuencode -m - | sed -ne 2p | cut -c-8

which takes depletes your entropy by 512 bytes before throwing most of it away, uses "uuencode", which needs an extra package, and sed and cut, and is generally nasty.)
_________________
Greybeard
Back to top
View user's profile Send private message
Zucca
Moderator
Moderator


Joined: 14 Jun 2007
Posts: 3711
Location: Rasi, Finland

PostPosted: Sat Sep 07, 2024 7:38 pm    Post subject: Reply with quote

I've used
Code:
tr -dc '[allovedcharacters]' < /dev/random | head -c <length>

_________________
..: Zucca :..

My gentoo installs:
init=/sbin/openrc-init
-systemd -logind -elogind seatd

Quote:
I am NaN! I am a man!
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 20485

PostPosted: Sat Sep 07, 2024 11:22 pm    Post subject: Reply with quote

While this is a script of more than one generator, it can be reduce to one of them. I never settled on one. Also, where credit is given, mistakes should be presumed to be mine.
Code:
# passphrase
bewaitered*Aile%retrovaccinate
tycoondiceboxsuppleheptene
patientpoisedkenoticxerotic.
pyxides sail letter distad.
calaisdeadeyeinfamyamidid
Code:
#!/bin/sh

set -efu

declare -a w n
w=( $( shuf -n3 /usr/share/dict/words ) )
n=( $( shuf -n2 -e \! \" \# \$ \% \& \' \( \) \* \+ \, \- \. \/ \: \; \< \= \> \? \@ \[ \\ \] \^ \_ \` \{ \| \} \~ ) )
for i in {0..2}; do
   if [[ $(( $RANDOM % 2 )) = 0 ]]; then
      w[$i]="${w[$i]^}"
   fi
done
printf '%s%s%s%s%s\n' "${w[0]}" "${n[0]}" "${w[1]}" "${n[1]}" "${w[2]}"

###############################################################################
# Remove words with:
#   - too many or too few characters
#   - apostrophes, hyphens, or capitalization
#   - Removing spaces is optional. (eccerr0r)
echo $(egrep '^[a-z]{4,7}$' /usr/share/dict/words|shuf -n4)|tr -d ' '

###############################################################################
# - avoid use of tr with printf (Hu)
printf '%s%s%s%s\n' $(grep -E '^[a-z]{4,7}$' /usr/share/dict/words|shuf -n4).

# With spaces
printf '%s %s %s %s\n' $(grep -E '^[a-z]{4,7}$' /usr/share/dict/words|shuf -n4).

# work regardless of the shuffle count
# relies on printf to
#   - discard the whitespace (newlines)
#   - then uses a bare echo to emit a newline at the end.
{ printf '%s' $(grep -E '^[a-z]{4,7}$' /usr/share/dict/words|shuf -n4); echo; }

_________________
Quis separabit? Quo animo?
Back to top
View user's profile Send private message
sMueggli
Guru
Guru


Joined: 03 Sep 2022
Posts: 497

PostPosted: Sun Sep 08, 2024 8:40 am    Post subject: Reply with quote

Code:
openssl rand -base64 12
Back to top
View user's profile Send private message
RumpletonBongworth
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2024
Posts: 82

PostPosted: Sun Nov 10, 2024 9:34 pm    Post subject: Reply with quote

Zucca wrote:
I've used
Code:
tr -dc '[allovedcharacters]' < /dev/random | head -c <length>

This is good but it demonstrates a common misunderstanding as to how tr(1) works. The square brackets should not be present unless either a) you wish for both brackets to be among the characters to be selected or b) you are writing a character class. For example:

Code:
# This is fine.
tr -dc 'allowedliterals'

# And so is this.
tr -dc '[:alnum:]'

Further, some implementations of tr(1) take the effective character set rather seriously.

Code:
# Where LC_CTYPE is effectively a UTF-8 locale, tr(1) will be unable to decode
# the input stream as UTF-8, with some implementations raising errors such as
# "tr: Illegal byte sequence". Coreutils tr(1) tolerates it, however.
tr -dc '[:alnum:]' < /dev/urandom

# Safer (and a bit faster, if using coreutils). Recommended if writing code that
# you intended to save or keep.
LC_ALL=C tr -dc '[:alnum:]' < /dev/urandom


EDIT: For the sake of completeness, I should add that square brackets are also employed for the [=equiv=] and [x*n] syntax.
Back to top
View user's profile Send private message
Zucca
Moderator
Moderator


Joined: 14 Jun 2007
Posts: 3711
Location: Rasi, Finland

PostPosted: Sun Nov 10, 2024 11:27 pm    Post subject: Reply with quote

RumpletonBongworth wrote:
Zucca wrote:
I've used
Code:
tr -dc '[allovedcharacters]' < /dev/random | head -c <length>

This is good but it demonstrates a common misunderstanding as to how tr(1) works. The square brackets should not be present unless either a) you wish for both brackets to be among the characters to be selected or b) you are writing a character class.
I'm not sure if I meant to write <allowedcharacters> (as in mandatory argument) or if I mistakenly added '[]' there.

RumpletonBongworth wrote:
Code:
# Where LC_CTYPE is effectively a UTF-8 locale, tr(1) will be unable to decode
# the input stream as UTF-8, with some implementations raising errors such as
# "tr: Illegal byte sequence". Coreutils tr(1) tolerates it, however.
tr -dc '[:alnum:]' < /dev/urandom

# Safer (and a bit faster, if using coreutils). Recommended if writing code that
# you intended to save or keep.
LC_ALL=C tr -dc '[:alnum:]' < /dev/urandom
And in some occurances setting LC_ALL=C will even boost the performance. I remember at least grep gaining a boost. But I've not encountered a tr version where unicode was a problem to it. Although my testing only includes coreutils and busybox. toybox, oddly, doesn't seem to have tr.
_________________
..: Zucca :..

My gentoo installs:
init=/sbin/openrc-init
-systemd -logind -elogind seatd

Quote:
I am NaN! I am a man!
Back to top
View user's profile Send private message
RumpletonBongworth
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2024
Posts: 82

PostPosted: Mon Nov 11, 2024 1:12 am    Post subject: Reply with quote

Zucca wrote:
But I've not encountered a tr version where unicode was a problem to it. Although my testing only includes coreutils and busybox. toybox, oddly, doesn't seem to have tr.

Yeah. For some reason, tr(1) tends to get a free pass when it comes to disregarding the effective character set and being multibyte-encoding unaware. Better implementations can be found in the BSD camp. Here's an interesting test that I conducted in macOS.

Code:
$ printf '\303\277' | tr -d '\377' | od -t x1
0000000    0a
0000001

There, it receives the UTF-8 encoding of "LATIN SMALL LETTER Y WITH DIAERESIS" and successfully decodes the bytes in accordance with the effective locale before proceeding to remove the character whose ordinal value is \377 (put another way: whose codepoint is U+FF). The poorer implementations don't even try, and will instead only remove the bytes whose values are 0xFF. Here's the outcome for coreutils.

Code:
$ printf '\303\277' | tr -d '\377' | od -t x1
0000000 c3 bf
0000002
Back to top
View user's profile Send private message
Zucca
Moderator
Moderator


Joined: 14 Jun 2007
Posts: 3711
Location: Rasi, Finland

PostPosted: Mon Nov 11, 2024 10:34 am    Post subject: Reply with quote

macOS encodes (some?) multibyte characters differently, on some cases, than Linux. At least that was the case/bug at some point. I wonder if this has something to do with that... Although I doubt it.

You could have two files with same name in same directory:
    One typed as
    Code:
    ¨o
    and another typed as
    Code:
    ö
    .
    Normally if you put 'ö' is the filename macOS (finder) would write it as '¨o' in the directory, but which would show as ö, which is correct, but the bytes still differ from plain 'ö', thus allowing two files with "same name" (visually) exist in the same directory.


Also the coreutils example you showed... seems to work correctly.
Perhaps I'm missing something... Since I haven't played with unicode related stuff too much.
_________________
..: Zucca :..

My gentoo installs:
init=/sbin/openrc-init
-systemd -logind -elogind seatd

Quote:
I am NaN! I am a man!
Back to top
View user's profile Send private message
RumpletonBongworth
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2024
Posts: 82

PostPosted: Tue Nov 19, 2024 12:27 am    Post subject: Reply with quote

Zucca wrote:
Also the coreutils example you showed... seems to work correctly.
Perhaps I'm missing something... Since I haven't played with unicode related stuff too much.

It doesn't. In fact, it cannot without a substantial update. Another example may prove illustrative, so let's compare coreutils tr(1) to GNU sed(1).

As regards the ensuing examples, keep in mind that '\303\277' is the portable way of expressing $'\xC3\xBF' as a printf(1) format string; two bytes representing the UTF-8 encoding of codepoint U+FF (a.k.a. LATIN SMALL LETTER Y WITH DIAERESIS).

Code:
$ uname -o
GNU/Linux
$ printf '\303\277' | sed -e 's/[[:alpha:]]//' | od -An -t x1
$


This outcome is correct because I have a UTF-8 locale in effect. Since GNU sed respects the effective character type and decodes the two incoming bytes to the single character/codepoint that they represent. It is then able to match - and substitute - this character by matching it against the [[:alpha:]] character class in a Unicode-aware fashion. Now let's try that with coreutils tr.

Code:
$ uname -o
GNU/Linux
$ printf '\303\277' | tr -d '[:alpha:]' | od -An -t x1
 c3 bf
$

Not ideal. Now let's try with the tr utility native to macOS, where I also have a UTF-8 locale in effect.

Code:
$ uname -o
Darwin
$ printf '\303\277' | tr -d '[:alpha:]' | od -An -t x1
$

Perfect. It works for exactly the same reason that GNU sed does. Of course, it remains possible to coerce US-ASCII semantics by setting LC_CTYPE and/or LC_ALL to C (or POSIX). Coming full circle then ...

Code:
$ uname -o
Darwin
$ tr -dc '[:alpha:]' < /dev/urandom
tr: Illegal byte sequence

Not only does it attempt to decode the incoming byte stream to codepoints but it also propagates the EILSEQ errors raised by the relevant libc routines, should they occur. That is, it is both a more capable and more rigorous implementation.
Back to top
View user's profile Send private message
Zucca
Moderator
Moderator


Joined: 14 Jun 2007
Posts: 3711
Location: Rasi, Finland

PostPosted: Tue Nov 19, 2024 7:19 am    Post subject: Reply with quote

Interesting. While tr -d '[:alnum:]' does not work on coreutils or busybox, but tr -d 'a-ö' does.
Code:
zucca@NBLK-WAX9X ~ $ printf 'ö' | od -An -t o1
 303 266
zucca@NBLK-WAX9X ~ $ printf 'ä' | od -An -t o1
 303 244
zucca@NBLK-WAX9X ~ $ printf '\303\244' | tr -d 'a-ö' | od -An -t x1
zucca@NBLK-WAX9X ~ $ printf '\303\244' | tr -d 'a-\303\244' | od -An -t x1
... so this points the problem being how tr interprets [:alnum:].
(ä is before ö in Finnish alphabet)
_________________
..: Zucca :..

My gentoo installs:
init=/sbin/openrc-init
-systemd -logind -elogind seatd

Quote:
I am NaN! I am a man!
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum