www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Random alphanumeric string

reply greenbyte <lysenko765 yandex.ru> writes:
```d
string randomAlphanumericString(int length)
{
     import std.array : array;
     import std.ascii : letters, digits;
     import std.random : choice, Random, unpredictableSeed;
     import std.range : generate, take;
     import std.conv : to;

     auto rnd = Random(unpredictableSeed);
     auto symbols = array(letters ~ digits);

     return generate!({ return symbols.choice(rnd); 
}).take(length).to!string;
}
```
Jun 20 2022
next sibling parent reply Cym13 <cpicard purrfect.fr> writes:
On Monday, 20 June 2022 at 11:49:24 UTC, greenbyte wrote:
 ```d
 string randomAlphanumericString(int length)
 {
     import std.array : array;
     import std.ascii : letters, digits;
     import std.random : choice, Random, unpredictableSeed;
     import std.range : generate, take;
     import std.conv : to;

     auto rnd = Random(unpredictableSeed);
     auto symbols = array(letters ~ digits);

     return generate!({ return symbols.choice(rnd); 
 }).take(length).to!string;
 }
 ```
This works, but just a gentle reminder that this must not be used to generate secrets (passwords, tokens, IDs whose disclosure could be problematic...). std.random is not cryptographically secure and therefore not fit for any security-related purpose. If on the other hand you're just generating public IDs, delimiters, that sort of things, then there is absolutely no issue with doing it this way.
Jun 20 2022
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Monday, 20 June 2022 at 12:40:05 UTC, Cym13 wrote:
 This works, but just a gentle reminder that this must not be 
 used to generate secrets (passwords, tokens, IDs whose 
 disclosure could be problematic...). std.random is not 
 cryptographically secure and therefore not fit for any 
 security-related purpose.
Can you explain this a little more? Is it possible to write our own randomness algorithms or manipulate Phobos Random()? SDB 79
Jan 30 2023
parent reply Cym13 <cpicard purrfect.fr> writes:
On Monday, 30 January 2023 at 17:13:17 UTC, Salih Dincer wrote:
 On Monday, 20 June 2022 at 12:40:05 UTC, Cym13 wrote:
 This works, but just a gentle reminder that this must not be 
 used to generate secrets (passwords, tokens, IDs whose 
 disclosure could be problematic...). std.random is not 
 cryptographically secure and therefore not fit for any 
 security-related purpose.
Can you explain this a little more? Is it possible to write our own randomness algorithms or manipulate Phobos Random()? SDB 79
There are many kinds of randomness. Phobos' is good for statistical analysis and things like choosing a random name within a list for a character. It produces numbers that show no clear pattern and are spread accross a given probability distribution. Very good for statistics. But for security you need more. Can people that see one number predict the next one? What if they see 10000 numbers? And if they cannot predict the next number, can they know what the previous one was? Do the numbers end up looping at some point? All of these scenarios lead to exploitable vulnerabilities if present in a security context. For example if the random number is used for a website's session token then it would allow you to deduce the session token of other people by looking at your own, giving you the tool to take over their account. This is what that comment as well as the warning in the documentation of std.random are about. I've discussed PRNG-related topics in Phobos in the past: - http://breakpoint.purrfect.fr/article/unpredictableSeed.html - http://breakpoint.purrfect.fr/article/cracking_phobos_uuid.html So how do we avoid that? There are pseudo-random generators that exist and are designed with more constraints to avoid any of the issues we mentioned and more. These are Cryptographically Secure Pseudo-Random Number Generators (CSPRNG). On linux for example /dev/urandom is such a CSPRNG. I know vibe.d exposes a CSPRNG as part of its library as well. I would love to see a CSPRNG interface in Phobos, but at the moment it doesn't seem to be a priority (https://issues.dlang.org/show_bug.cgi?id=16493).
Jan 30 2023
next sibling parent Kagamin <spam here.lot> writes:
On Tuesday, 31 January 2023 at 06:29:24 UTC, Cym13 wrote:
 http://breakpoint.purrfect.fr/article/cracking_phobos_uuid.html
It's not just secrecy, there's also variability requirement. A 32-bit identifier is unsuitable as an uuid, as they will repeat often.
Jan 31 2023
prev sibling parent Siarhei Siamashka <siarhei.siamashka gmail.com> writes:
On Tuesday, 31 January 2023 at 06:29:24 UTC, Cym13 wrote:
 Phobos' is good for statistical analysis and things like 
 choosing a random name
 within a list for a character. It produces numbers that show no 
 clear pattern
 and are spread accross a given probability distribution. Very 
 good for statistics.
It's good for statistics only if we ignore performance, which is actually horribly bad in `std.random`. Things like random array shuffling are several times slower than they could have been. Some of the Phobos problems are listed at https://github.com/libmir/mir-random#comparison-with-phobos What would be a realistic plan to improve `std.random` in Phobos? Or is it a better idea to rely on third-party libraries for this functionality? One of the actual use cases of std.random is producing deterministic randomish looking sequences for unit tests via a deterministic seed. If bounded integers generation in `std.random.uniform` is optimized, then these sequences will change. Also the default generator is 32-bit Mersenne Twister, which is bad for 64-bit systems because generating a random size_t index is done via producing two 32-bit numbers and gluing them together. But changing the default generator to something else will may break some applications.
Jan 31 2023
prev sibling parent Salih Dincer <salihdb hotmail.com> writes:
It could be more flexible if it could be used as a range without 
packing this code too much:

```d
auto randomAlphanumeric(string S)(size_t len)
{
   import std.array  : array;
   import std.random : choice, Random, unpredictableSeed;
   import std.range  : generate, take;

   auto rnd = Random(unpredictableSeed);
   auto gen = generate!(() => S.array.choice(rnd));

   return gen.take(len);
}

import std.ascii, std.stdio;

void main()
{

   auto str = 16.randomAlphanumeric!lowercase;
   auto hex = 16.randomAlphanumeric!hexDigits;

   foreach(c; str)
   {
     c.write;
   }
   writeln("\n", hex); /* Prints:
   tqapxlqouvbpgsia
   862C234EE3D9CFC4
*/
}
```

I would prefer to use an enum as it is simple.  For example, it's 
as simple as this:

```d
generate!(function char() => uniform!Enum)
```

Put that in a function and enums of type char into a struct as 
well:

```d
auto randomFromEnumerate(E)(size_t len)
{
   import std.random : rnd = uniform;
   import std.range  : generate, take;

   return generate!(function char() => rnd!E).take(len);
}

struct E {
   enum num {
     o = '0', p, q, r, s, t, u, v, w, x,
   }
   enum hex {
     o = '0', p, q, r, s, t, u, v, w, x,
     a = 'A', b, c, d, e, f
   }
   enum dna {
     a = 'A', c = 'C', g = 'G', t = 'T'
   }
   enum lowercase {
     a = 'a', b, c, d, e, f, g, h, i, j, k, l,
     m, n, o, p, q, r, s, t, u, v, w, x, y, z
   }
}

void main()
{
   10.randomFromEnumerate!(E.dna).writeln;
   // CGTGAGGGTC
}
```
SDB 79
Jan 30 2023