Generate a string of alphanumeric characters

Hi,
I want a script of a code that will allow me to generate all possible combinations of alphanumberica characters of length 12 such that each string will contain numbers and either small or capital letters.
For example a string may look like this: 123AB45cd678.

I think you might want to rethink your post. Just using base36 numbers in bash to answer your post:

$ echo $((36#zzzzzzzzzzzz))
4738381338321616895

That is the largest 12 digit number in base36 - the gigantic number. It could easily take a desktop computer long time to count that high.
Every combination of base 36 number taken 12 at a time is much larger than the stupidly large number above.

I'm positive you need to tell us what you are trying to do, I've answered the question of how to print a decimal version base36 number, which is not what you asked. Mostly for completeness.

echo $((base#number))

Can you please tell us your requirement - example: generate 12 character passwords for linux.

Hi,
the number of all combinations from your condition is equal to 2.6543489742975863e+21
Where will you put everything? ...even if you will write in C... :slight_smile:
set the condition exactly

@jim mcnamara & @nezabudka: Out of sheer curiosity - how did you derive those numbers? For me, the ASCII alphabet has 26 characters; upper case and lower case plus 10 digits makes that 62. 62^12=3,23e+21 - am I wrong?

1 Like

Yes. I was mistaken I considered 61. I need to learn the alphabet :mad:

I just used bash to transform zzzzzzzzzzz , the highest value for 12 digits of base36, into decimal. It may not even be correct. Sorry for the confusion.

The idea of the OP's post seemed to be wildly unattainable with modern desktop hardware and/or required specialty software. Plus, where do you store the output? So I went with a quick version, since I do not have any bignum software on this box.

And base62 is correct, my explanation was for base64. I really was not clear.

Using {@,_} for "positions" 63 and 64 is bash behavior, I believe.

Note that there are only eleven z 's in the string in red above; not twelve.

I thought most systems these days came with bc and/or dc .

$ echo '62 12^p' | dc
3226266762397899821056
$ echo '62^12' | bc
3226266762397899821056
$ 

Unfortunately, standard versions of bc are only required to handle input bases between 2 and 16 (inclusive) and dc isn't in the standards (but frequently has the same limits) so calculation in base 36 or base 62 aren't handled directly by these utilities. (On many systems, bc is implemented as a front-end to dc .) But from the above bc and dc output, I can say that 1000000000000 (base 62) (that is a digit 1 followed by twelve digit 0s) is 3226266762397899821056 (base 10).

1 Like

Well, better let's look at the example.
First, let's make the sequence of 62 characters.

echo $'\n'{{0..9},{A..Z},{a..z}}

Now we have 62 characters per line (Excluding the first line with the character $'\n' ).
Let's see how many combinations of 2 characters are possible.

echo $'\n'{{0..9},{A..Z},{a..z}}{{0..9},{A..Z},{a..z}} | wc -l

Subtract 1 ( $'\n' ) from the resulting value, and we get the number 3844 variants.
Add chili pepper to three and get...

time echo $'\n'{{0..9},{A..Z},{a..z}}{{0..9},{A..Z},{a..z}}{{0..9},{A..Z},{a..z}} | wc -l
> 238328

And the time spent by my laptop will be

real    0m0,983s

And the last option of the four elements. Prevent you from even running this command!

time echo $'\n'{{0..9},{A..Z},{a..z}}{{0..9},{A..Z},{a..z}}{{0..9},{A..Z},{a..z}}{{0..9},{A..Z},{a..z}} | wc -l
>14776336 #minus 1
real    2m49,353s

for the time being the command almost paralyzed my laptop.
And this is only a combination of 4 items from 62
Thanks for attention.

May i add a few corrections to your estimations? Not, that these will affect the practicality of the outcome in any way, but....

From the wording it follows that we work case-sensitive so that we have a base set of 62 characters and want to find the the 12-combinations.

It also follows that we have to subtract from this the number of all-digit 12-combinations (if basing on multisets, see below) and the number of all-character 12-combinations. It has to be clarified if we still talk combinations without duplicities (as i do assume), that is, 12-tuples of different elements of the base set, or combinations with duplicities.

Lets us for the moment neglect the restricting task and calculate what i'd call the number of the "base set":

If we use combinations without duplicities, that is 12-tuples of different elements of the 62-element set we get n! / ( (n-k)! k! ) or "n over k", the "binomial coefficient", combinations, which is (62! / ( 50! * 12! )) approximately 10^^85 / 10^^64 * 10^^9 ~ 10^^12.

If we use combinations with duplicities (or, basically, a "set of multisets") we need to take into account that an identical element in two different places can be exchanged without changing the combination and hence we get (n+k-1)! / ((n-1)! * k!) . 73! / (61! * 12!) is approximately 10^^105 / 10^^83 * 10^^9 ~ 10^^13. The notation for this number is similar to the binomial coefficient ("n over k") but with double braces, i don't know its english name.

We need to reduce the first possible result now by the number of all-character permutations (50 over 12, ~10^^11) in the first case and the second result by this plus the number of all-digit combinations ( multiset 10 over 12, ~10^^7). Both operations won't change the order of magnitude of the results so we get ~10^^12 or ~10^^13 as the respective cardinality of the result sets.

(I do not have any hope this will really help anybody but it was fun nevertheless.)

bakunin

2 Likes

Thanks @bacunin, very helpful. I myself recently
wrote a program to rearrange the elements.
It can be slightly modified and used to generate just the case as you described.
That a series would consist only of unique values. Just in case,
I will give here my program without changes.
It sorts the represented string first argument by dictionary order,
creates all possible combinations without duplicate elements.
Selects a line from the middle of the list and displays it on the screen.
Nothing prevents to remake the program for outputting all
intermediate lines with permutation as in the second program.
With the input data from 10 elements this program worked on my laptop real 5m30,979s

#!/bin/bash
: << SPRAVKA
name test.sh version bash 4.4 (x86_64 rhel)
usage: ./test.sh OPAZWYBCN
"od -An -t x2 -w26" can be replaced by "xxd -ps -c26" or hexdump -e '"%02X"'
SPRAVKA
middle() {
        data=$(echo -n "$1" | od -An -t x2 -w26 | sed 's/ \|00//g;s/../a[n++]=\U&;/g')
        bc <<<'define prt(a[],n) { auto i
        for(i=0; i<n; i++) print a
                print "\n"
        }
        define perm(a[], s, n) { auto tmp, i
        if(s == n-1){ o=prt(a[], n)} else {
                for( i=s; i < n; i++) {
                        tmp=a
                        a = a
                        a = tmp
                        o=perm(a[], s+1, n)
                        a = a
                        a = tmp
                }
        }
        }
        ibase=16; obase=10
        '"$data"'
        o=perm(a[], 0, n)'
}
echo -e "$(middle "$1" | sed -r 's/\w{2}/\\x&/g')" | sort |
        head -$(bc <<<'n='"${#1}"'; s=1; for(i=1;i<=n;i++) s*=i; s/2') | tail -1
#!/bin/bash

middle() {
        bc <<<'define prt(a[],n) { auto i
        for(i=0; i<n; i++) print a
                print "\n"
        }
        define perm(a[], s, n) { auto tmp, i
        if(s == n-1){ o=prt(a[], n)} else {
                for( i=s; i < n; i++) {
                        tmp=a
                        a = a
                        a = tmp
                        o=perm(a[], s+1, n)
                        a = a
                        a = tmp
                }
        }
        }
        a[0]=1; a[1]=2; a[2]=3; a[3]=4; n=4
        o=perm(a[], 0, n)'
}
middle

I do not think that it will interfere. thanks

Thanks for the update, Don. I was using an old version (32bit) cygwin on an old PC. bc gave me a range error. However, 11 vs 12 "z's" is my mistake. That may be why bash was able to do the calculation.

Or maybe do you need an algorithm for randomly selecting 12 characters from 62 ?

shuf -e {{0..9},{A..Z},{a..z}} -zn12