C#
string manipulation
shuffle algorithm
programming
tutorial

Shuffle string c

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Shuffling a string means producing a random permutation of its characters. In C#, this is slightly indirect because strings are immutable, so you usually convert to a character buffer, shuffle it, then build a new string. This guide covers correct and unbiased approaches, including secure randomness when needed.

Core Topic Sections

Understand immutability and algorithm choice

Since string cannot be modified in place, the standard pattern is:

  1. Copy to char[].
  2. Shuffle the array.
  3. Construct new string from shuffled array.

For unbiased shuffling, use Fisher and Yates. Sorting by random key is concise but can introduce bias and unnecessary overhead.

Fisher and Yates shuffle in C#

csharp
1using System;
2
3public static class StringShuffle
4{
5    public static string Shuffle(string input, Random rng)
6    {
7        char[] chars = input.ToCharArray();
8
9        for (int i = chars.Length - 1; i > 0; i--)
10        {
11            int j = rng.Next(i + 1);
12            (chars[i], chars[j]) = (chars[j], chars[i]);
13        }
14
15        return new string(chars);
16    }
17
18    public static void Main()
19    {
20        var rng = new Random();
21        Console.WriteLine(Shuffle("abcdef", rng));
22    }
23}

This runs in linear time and gives uniform permutations if random source is uniform.

Avoid repeated new Random() mistakes

Creating Random repeatedly in tight loops can produce similar sequences due to seeding behavior.

Bad pattern:

  1. Create new Random() per call.
  2. Call function rapidly.
  3. See repeated shuffle outputs.

Prefer shared instance:

csharp
private static readonly Random SharedRng = new Random();

Or use thread-safe APIs in modern .NET when concurrency is required.

Cryptographic randomness when needed

If shuffled strings are security-sensitive, use cryptographic RNG instead of Random.

csharp
1using System;
2using System.Security.Cryptography;
3
4public static string ShuffleSecure(string input)
5{
6    char[] chars = input.ToCharArray();
7
8    for (int i = chars.Length - 1; i > 0; i--)
9    {
10        int j = RandomNumberGenerator.GetInt32(i + 1);
11        (chars[i], chars[j]) = (chars[j], chars[i]);
12    }
13
14    return new string(chars);
15}

This is appropriate for tokens, challenge strings, and security workflows.

Keep behavior explicit for repeated characters

When input contains duplicate characters, multiple permutations map to identical output strings. That is expected and not a bug.

Example:

  1. Input aab has only three distinct arrangements.
  2. Uniform shuffle still samples index permutations uniformly.

Document this in tests to avoid confusion during QA.

Testing shuffle quality pragmatically

You cannot “prove” randomness in one test, but you can detect obvious flaws:

  1. Ensure output length equals input length.
  2. Ensure character multiset is unchanged.
  3. Check distribution sanity across many runs.

Simple multiset check:

csharp
1using System.Collections.Generic;
2
3static bool SameChars(string a, string b)
4{
5    if (a.Length != b.Length) return false;
6
7    var freq = new Dictionary<char, int>();
8    foreach (var c in a) freq[c] = freq.GetValueOrDefault(c) + 1;
9    foreach (var c in b)
10    {
11        if (!freq.ContainsKey(c) || freq[c] == 0) return false;
12        freq[c]--;
13    }
14    return true;
15}

These tests catch most implementation errors quickly.

Performance considerations

For typical string sizes, Fisher and Yates cost is negligible. For very high volume:

  1. Reuse buffers where safe.
  2. Avoid extra allocations.
  3. Benchmark with realistic text lengths.

Do not optimize prematurely if shuffle is not a hot path.

Common use cases

Shuffled strings appear in:

  1. Word games and puzzle apps.
  2. Test data randomization.
  3. User-facing random presentation ordering.

Use secure random only where threat model justifies it.

Common Pitfalls

  • Using sort-by-random-key and assuming perfectly uniform permutations.
  • Creating Random repeatedly and getting correlated outputs.
  • Forgetting string immutability and expecting in-place modification.
  • Using non-cryptographic randomness for security-sensitive flows.
  • Testing only one or two outputs and assuming implementation is correct.

Summary

  • In C#, shuffle strings by converting to char array and rebuilding string.
  • Fisher and Yates is the standard unbiased linear-time algorithm.
  • Reuse random generators correctly to avoid repeated patterns.
  • Use cryptographic RNG for security-sensitive shuffles.
  • Validate both correctness and distribution sanity with targeted tests.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.