diff --git a/core/lib/Drupal/Component/Utility/Random.php b/core/lib/Drupal/Component/Utility/Random.php
index 16190d8f66949585db85314ea2717eeb5b78b359..799520a78393f2bd3b08614067ee19c439021924 100644
--- a/core/lib/Drupal/Component/Utility/Random.php
+++ b/core/lib/Drupal/Component/Utility/Random.php
@@ -33,6 +33,13 @@ class Random {
    */
   protected $names = [];
 
+  /**
+   * A list of unique names generated by machineName().
+   *
+   * @var string[]
+   */
+  protected array $machineNames = [];
+
   /**
    * Generates a random string of ASCII characters of codes 32 to 126.
    *
@@ -130,6 +137,51 @@ public function name($length = 8, $unique = FALSE) {
     return $str;
   }
 
+  /**
+   * Generates a string containing lowercase letters and numbers.
+   *
+   * This method is used to generate strings that are compliant with Drupal
+   * machine names. This doesn't include underscores, dashes and periods since
+   * those are not compatible with all machine names.
+   *
+   * @param int $length
+   *   Length of random string to generate.
+   * @param bool $unique
+   *   If TRUE ensures that the random string returned is unique.
+   *   Defaults to FALSE.
+   *
+   * @return string
+   *   Randomly generated string.
+   *
+   * @throws \RuntimeException
+   *   Thrown if a unique machine name cannot be generated within the allowed
+   *   number of random attempts.
+   *
+   * @see \Drupal\Component\Utility\Random::string()
+   */
+  public function machineName(int $length = 8, bool $unique = FALSE): string {
+    $values = array_merge(range('a', 'z'), range(0, 9));
+    $start_characters = range('a', 'z');
+    $counter = 0;
+
+    do {
+      if ($counter == static::MAXIMUM_TRIES) {
+        throw new \RuntimeException('Unable to generate a unique random machine name');
+      }
+      $str = $start_characters[array_rand($start_characters)];
+      for ($i = 1; $i < $length; $i++) {
+        $str .= $values[array_rand($values)];
+      }
+      $counter++;
+    } while ($unique && isset($this->machineNames[$str]));
+
+    if ($unique) {
+      $this->machineNames[$str] = TRUE;
+    }
+
+    return $str;
+  }
+
   /**
    * Generate a string that looks like a word (letters only, alternating consonants and vowels).
    *
diff --git a/core/tests/Drupal/TestTools/Random.php b/core/tests/Drupal/TestTools/Random.php
index 46a4729b0d9fff34feb93afc9074dafbbc83f7b9..35de4a781446ae3056e8ba092b8cde9c1a7c216d 100644
--- a/core/tests/Drupal/TestTools/Random.php
+++ b/core/tests/Drupal/TestTools/Random.php
@@ -101,7 +101,7 @@ public static function stringValidate(string $string): bool {
    * @see \Drupal\Component\Utility\Random::name()
    */
   public static function machineName(int $length = 8): string {
-    return static::getGenerator()->name($length, TRUE);
+    return static::getGenerator()->machineName($length, TRUE);
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Component/Utility/RandomTest.php b/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
index efde521f3effe4ae9894c8f66e3ce25b176340b9..e1682b67f5b7179610e8d152ad8cc6146e02ee0c 100644
--- a/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
@@ -115,6 +115,51 @@ public function testRandomStringNonUnique() {
     $this->assertTrue(TRUE, 'No exception thrown when uniqueness is not enforced.');
   }
 
+  /**
+   * Tests unique random name generation.
+   *
+   * @covers ::machineName
+   */
+  public function testRandomMachineNamesUniqueness(): void {
+    $names = [];
+    $random = new Random();
+    for ($i = 0; $i <= 25; $i++) {
+      $str = $random->machineName(1, TRUE);
+      $this->assertArrayNotHasKey($str, $names, 'Generated duplicate random name ' . $str);
+      $names[$str] = TRUE;
+    }
+  }
+
+  /**
+   * Tests infinite loop prevention whilst generating random names.
+   *
+   * @covers ::machineName
+   */
+  public function testRandomMachineNameException(): void {
+    // There are fewer than 100 possibilities so an exception should occur to
+    // prevent infinite loops.
+    $this->expectException(\RuntimeException::class);
+    $random = new Random();
+    for ($i = 0; $i <= 100; $i++) {
+      $random->machineName(1, TRUE);
+    }
+  }
+
+  /**
+   * Tests random name generation if uniqueness is not enforced.
+   *
+   * @covers ::machineName
+   */
+  public function testRandomMachineNameNonUnique(): void {
+    // There are fewer than 100 possibilities meaning if uniqueness was
+    // enforced, there would be an exception.
+    $random = new Random();
+    for ($i = 0; $i <= 100; $i++) {
+      $random->machineName(1);
+    }
+    $this->expectNotToPerformAssertions();
+  }
+
   /**
    * Tests random object generation to ensure the expected number of properties.
    *