-4

I am writing a code to create a random password without duplicates for my project. My code is the form of randomly picking numbers and letters from the string. However, I would like to ask how to eliminate duplication in string data type, not int.

public  static  class StringUtils
{
    private  const  string PASSWORD_CHARS = 
         "0123456789abcdefghijklmnopqrstuvwxyz" ;

    public  static  string GeneratePassword ( int length)
    {
        var sb = new System.Text.StringBuilder (length);
        var r = new System.Random ();

        for ( int i = 0 ; i <length; i ++)
        {
            int      pos = r.Next (PASSWORD_CHARS.Length);
             char     c = PASSWORD_CHARS [pos];
            sb.Append (c);
        }

        return sb.ToString ();
    }
}

I kept searching and looked for a way, but I couldn't find a solution.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • You mean that you don't want to re-use any of the characters? Shuffle the characters and then just take the first `length` number of them. (Note: Intentionally avoiding duplicate characters makes the passwords *less* secure, not *more*.) – David Dec 14 '22 at 02:35
  • A randomly generated password is a password to solve a puzzle. It's right to make sure that it doesn't. – wndud 1731 Dec 14 '22 at 02:39
  • 1
    @wndud1731 - What does that mean? – Enigmativity Dec 14 '22 at 02:42
  • I mean, I'm trying to generate random numbers and letters that don't overlap for horror games. – wndud 1731 Dec 14 '22 at 02:44
  • @wndud1731 - And, again, what does that mean? "don't overlap for horror games" – Enigmativity Dec 14 '22 at 02:45
  • Do you mean that in the game, that the player needs to solve a puzzle by guessing a password? –  Dec 14 '22 at 02:46
  • That's right, given random letters and numbers, players have to walk around the room looking for clues and solving passwords. – wndud 1731 Dec 14 '22 at 02:48
  • 2
    DO NOT create the `Random` object inside the `GeneratePassword` method. Create a single instance and use that every time. If you're using .NET 6 or later, use the `Shared` property to get a system-generated instance that is also thread-safe. – jmcilhinney Dec 14 '22 at 02:53
  • Are you saying that you want each password to be unique, or each character within a single password to be unique? I inferred the former but maybe it's the latter. It helps to be clear about what you want. – jmcilhinney Dec 14 '22 at 02:55
  • To create a random four-digit number without duplication, We succeeded without any problems. However, random letters that fit the four digits are having a hard time producing them. Ex) password : 2856 => # = 2, $ = 8, @ = 5, & = 6 – wndud 1731 Dec 14 '22 at 02:58
  • @Enigmativity I apologize for my mistake. It means that random numbers that are not duplicated are used for my horror game project. – wndud 1731 Dec 14 '22 at 03:00
  • @wndud1731 - I'm really struggling to understand what you mean. I understand you don't want duplicates, but I don't understand why. – Enigmativity Dec 14 '22 at 03:04
  • I'll tell you again. You get random numbers in a horror game. This creates random characters in the room, and each of those characters is assigned a number of characters. I want the player to look at the letters and numbers generated in the room and solve the password. This requires random numbers and characters that do not duplicate. Ex) the password : 5847 => @ = 5, # = 8, $ = 4, & = 7 – wndud 1731 Dec 14 '22 at 03:10
  • @wndud1731 - You're not explaining why you need to avoid duplicates. You just keep stating that you want to avoid duplicates. – Enigmativity Dec 14 '22 at 03:30

1 Answers1

1

Give this humdinger a go:

private static Random r = new Random();

public static string GeneratePassword(int length) =>
    new string(PASSWORD_CHARS.OrderBy(x => r.Next()).Take(length).ToArray());
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • How does this work? Does the `OrderBy` take `MOD PASSWORD_CHARS.Length` of `r.Next()`? – Robert Harvey Dec 14 '22 at 02:48
  • Ah, it's just length number of random integers between 1 and int.MaxValue, placed in ascending order, corresponding to the ordinal positions of the characters. – Robert Harvey Dec 14 '22 at 02:50
  • It's just length number of characters after the array was sorted randomly. – Enigmativity Dec 14 '22 at 02:52
  • The one thing I would change is using `NextDouble` rather than `Next`. It's not a big deal but `Next` calls `NextDouble` internally anyway, so there's no point doing the extra calculation to turn that `double` into an `int`. – jmcilhinney Dec 14 '22 at 02:57
  • @jmcilhinney - It doesn't seem to to me. The internal call is to `internal ulong NextUInt64()`. The implementation of `NextDouble` is `return (double)(NextUInt64() >> 11) * 1.1102230246251565E-16;`. It seems to be the other way round to what you're suggesting. – Enigmativity Dec 14 '22 at 03:00
  • @Enigmativity, that may be the .NET Core implementation and they may have changed it. I just took a look at the .NET Framework implementation, which is what I'd looked at previously, and I was not quite correct but almost. `NextDouble` calls `Sample` and returns the result, while `Next` calls `Sample` and then does some extra processing before returning the result. It probably makes little difference either way, mind you. – jmcilhinney Dec 14 '22 at 03:09
  • @jmcilhinney - `Next` is implemented as `return InternalSample();`. `NextDouble` calls `Sample` which is implemented as `return (InternalSample()*(1.0/MBIG));` There is only integer math in `InternalSample`. – Enigmativity Dec 14 '22 at 03:19
  • Search for "random without duplicates c#" for explanation of this answer. Note that it is the shortest to write code, but not necessary the best (again, explanations of that are in the previous search results and duplicate), especially if you need shuffling in your program anyway you'd have helper function to produce that randomized sequence on demand (with O(number_of_picks) time for each number, vs. this code of O(num_letters* log(num_letters)) ). – Alexei Levenkov Dec 14 '22 at 03:34
  • 1
    I think you're right. I may have looked at the wrong overload and come to the wrong conclusion. – jmcilhinney Dec 14 '22 at 03:43
  • Unity specific you could also use [`UnityEngine.Random.value`](https://docs.unity3d.com/ScriptReference/Random-value.html) – derHugo Dec 14 '22 at 07:43