URL-safe pseudorandom string generator in C# public static class SimpleToken
{
    const string TOKENALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.";
    static string NewToken(int length = 16)
    {
        var rnd = new RNGCryptoServiceProvider();
        var tokenBytes = new byte[length];
        rnd.GetBytes(tokenBytes);
        var token =
            Enumerable
                .Range(0, length)
                .Select(i =&gt; TOKENALPHABET[tokenBytes[i] % TOKENALPHABET.Length])
                .ToArray();

        return new String(token);
    }
}


I needed a quick and dirty(?) way to generate long urls for onetime use. It's a simple login-scheme where a user enters his e-mail and gets a one-time URL for logging in. The URL is discarded after one use.

I.e. http://example.com/tokenlogin/3cuzLkh8GcANjqnWcijEeJIHphHx6ZDwfj-2XTR4bfkkqmzmmFYAY2tWsZWST1.5
const string TOKENALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.";



I learnt the hard way that the problem with using . in a URL token sent by e-mail is that certain mail clients (Outlook in particular) will attempt to auto-detect URLs in a plain text email, but will exclude a trailing . from the inferred URL, so when your user clicks on the auto-generated link they send an invalid token. I suggest that you change . to _.




    static string NewToken(int length = 16)



Length in what units? Generally with cryptographic stuff it's clearer to explicitly use bits as the unit of length.




        var rnd = new RNGCryptoServiceProvider();



As already noted in comments, this is IDisposable and the standard using pattern is preferred.




        var token =
            Enumerable
                .Range(0, length)
                .Select(i =&gt; TOKENALPHABET[tokenBytes[i] % TOKENALPHABET.Length])
                .ToArray();



Firstly, this could be simplified to

        var token =
            tokenBytes
                .Select(b =&gt; TOKENALPHABET[b % TOKENALPHABET.Length])
                .ToArray();


But secondly, by only using 6 bits per byte you're throwing away 25% of the entropy which the system just produced for you. On busy servers, cryptographic-grade entropy is a valuable resource and you should only request as much as you need.