# Tutorial: Implement a quantum random number generator in Q#

Note

The examples in this topic use the Microsoft Quantum Development Kit (Classic QDK) and are not yet compatible with the Azure Quantum Development Kit Preview (Modern QDK). For more information about the Modern QDK, see the QSharp GitHub Wiki.

Learn to write a basic quantum program in Q# that leverages the nature of quantum mechanics to produce a random number.

In this tutorial, you'll learn how to

- Create a Q# project.
- Prepare your development environment for writing quantum programs in Q#.
- Understand how Q# programs are structured.
- Work with qubits and superposition to build a quantum random number generator.

## Prerequisites

To run the code sample in the Copilot in Azure Quantum:

- A Microsoft (MSA) email account.

To develop and run the code sample in your local dev environment:

- Install the Quantum Development Kit (QDK) using your preferred language and development environment. This tutorial presents the solution in three different formats:
- Q# standalone
- Q# and Python
- Q# and C#

- If you already have the QDK installed, make sure you have updated the QDK (and the Python qsharp package, if applicable) to the latest version.

- Install the Quantum Development Kit (QDK) using your preferred language and development environment. This tutorial presents the solution in three different formats:

## Creating a Q# project

The first thing you need to do is to create a new Q# project. This tutorial uses the environment based on Q# applications with VS Code, but you can use your preferred IDE.

To create a new project in Visual Studio Code:

- Select
**View**->**Command Palette**and select**Q#: Create New Project**. - Select
**Standalone console application**. - Select a location to save the project, name it
**Qrng**, and select**Create Project**. - When the project is successfully created, select
**Open new project...**in the lower right.

This generates two files: the project file, *Qrng.csproj*, and a Q# application template, *Program.qs*, that you will use to write your application.

## Write a Q# operation

Now, replace the contents of the *Program.qs* file with the following code:

```
namespace Qrng {
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
operation SampleQuantumRandomNumberGenerator() : Result {
// Allocate a qubit
use q = Qubit();
// Put the qubit to superposition
// It now has a 50% chance of being measured 0 or 1
H(q);
// Measure the qubit value and reset the qubit
return MResetZ(q);
}
}
```

Now take a look at new code.

- First, you
`open`

the necessary namespaces from the Q# libraries for the functions and operations needed. - You define the
`SampleQuantumRandomNumberGenerator`

operation, which takes no input and produces a value of type`Result`

. The`Result`

type represents the result of a measurement and can have two possible values:`Zero`

or`One`

. - Allocate a single qubit with the
`use`

keyword. - Use the
`H`

(Hadamard) operation to place the qubit in an equal superposition. - Use the
`MResetZ`

operation to measure the qubit, return the measured value (`Zero`

or`One`

), and then reset the qubit so it may be used again.

A qubit is a unit of quantum information that can be in superposition. (For more information about qubits and superposition, see Understanding quantum computing.) When measured, a qubit can only be either in the **0** state or in the **1** state. However, before measurement, the state of the qubit represents the *probability* of reading either a **0** or a **1** with a measurement. In this example, before the measurement the qubit is in an equal superposition, that is there is a probability of 50% of reading **0** and 50% of reading **1**. You can use this probability to generate random numbers.

The user-defined `SampleQuantumRandomNumberGenerator`

operation introduces the `Qubit`

datatype, which is native to Q#. You can only allocate a `Qubit`

with a `use`

statement. When it gets allocated, a qubit is always in the `Zero`

state.

By putting the qubit in superposition with the `H`

operation and measuring it with the `MResetZ`

operation, the result is a different value each time the code is invoked.

### Visualizing the code with the Bloch sphere

In the Bloch sphere, the north pole represents the classical value **0** and the south pole represents the classical value **1**. Any superposition can be represented by a point on the sphere (represented by an arrow). The closer the end of the arrow to a pole the higher the probability the qubit collapses into the classical value assigned to that pole when measured. For example, the qubit state represented by the arrow in the following figure has a higher probability of giving the value **0** if you measure it.

You can use this representation to visualize what the code is doing:

- First, start with a qubit initialized in the state
**0**and apply an`H`

operation to create an equal superposition in which the probabilities for**0**and**1**are the same.

- Then measure the qubit and save the output:

Since the outcome of the measurement is random and the probabilities of measuring **0** and **1** are the same, you have obtained a completely random bit. You can call this operation several times to create integers. For example, if you call the operation three times to obtain three random bits, you can build random 3-bit numbers (that is, a random number between 0 and 7).

## Create a complete random number generator

Now that you have a Q# operation that generates random bits, you can combine multiple random bits to build a complete quantum random number generator. You can run your program as a standalone Q# application, or use a host program in Python or .NET to call your Q# code.

### Define the random number generator logic

First, outline what the logic of a random number generator should be, provided there already exists a random bit generator:

- Define
*max*as the maximum number you want to generate. - Define the number of random bits that you need to generate. This is done by calculating how many bits,
*numBits*, you need to express integers up to*max*. - Generate a random bit string that is
*numBits*in length. - If the bit string represents a number greater than
*max*, go back to step three. - Otherwise, the process is complete. Return the generated number as an integer.

### Define the operation

Next, define the `SampleRandomNumberInRange`

operation, which uses a `for`

loop to repeatedly call the `SampleQuantumRandomNumberGenerator`

operation and build a string of bits.

Modify *Program.qs* to add the new operation:

```
namespace Qrng {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
operation SampleQuantumRandomNumberGenerator() : Result {
// Allocate a qubit
use q = Qubit();
// Put the qubit to superposition
// It now has a 50% chance of being measured 0 or 1
H(q);
// Measure the qubit value
return MResetZ(q);
}
operation SampleRandomNumberInRange(max : Int) : Int {
mutable output = 0;
repeat {
mutable bits = [];
for idxBit in 1..BitSizeI(max) {
set bits += [SampleQuantumRandomNumberGenerator()];
}
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
}
```

Now take a moment to review the new operation.

- In order to calculate the number of bits needed to express integers up to
`max`

, use the`BitSizeI`

function. - The
`SampleRandomNumberInRange`

operation uses a`repeat`

loop to generate random numbers until it generates one that's equal to or less than`max`

. - The
`for`

loop inside`repeat`

works exactly the same as a for loop in other programming languages. - In this example,
`output`

and`bits`

are mutable variables. A mutable variable is one that can change during the computation. You use the`set`

directive to change the value of a mutable variable. - The
`ResultArrayAsInt`

function converts the bit string to a positive integer.

The `Qrng`

program can now generate random numbers.

## Run the random number generator program

Using your final version of the Q# code,

```
namespace Qrng {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
operation SampleQuantumRandomNumberGenerator() : Result {
// Allocate a qubit
use q = Qubit();
// Put the qubit to superposition
// It now has a 50% chance of being measured 0 or 1
H(q);
// Measure the qubit value
return MResetZ(q);
}
operation SampleRandomNumberInRange(max : Int) : Int {
mutable output = 0;
repeat {
mutable bits = [];
for idxBit in 1..BitSizeI(max) {
set bits += [SampleQuantumRandomNumberGenerator()];
}
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
}
```

Select the tab for your preferred language and environment and follow the instructions for running or calling your Q# program.

- Copilot in Azure Quantum
- Standalone Q# application with Visual Studio or Visual Studio Code
- Python with Visual Studio Code or the command prompt
- C# with Visual Studio Code or Visual Studio

You can test your Q# code with the Copilot in Azure Quantum free of charge - all you need is a Microsoft (MSA) email account. For more information about the Copilot in Azure Quantum, see Explore Azure Quantum.

A standalone Q# application requires an `EntryPoint`

so the Q# compiler knows where to start the program. To create the full Q# application, add the following entry point to your Q# program, *Program.qs*:

```
namespace Qrng {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
operation SampleQuantumRandomNumberGenerator() : Result {
// Allocate a qubit.
use q = Qubit();
// Put the qubit to superposition.
H(q);
// It now has a 50% chance of being measured 0 or 1.
// Measure the qubit value.
return MResetZ(q);
}
operation SampleRandomNumberInRange(max : Int) : Int {
mutable output = 0;
repeat {
mutable bits = [];
for idxBit in 1..BitSizeI(max) {
set bits += [SampleQuantumRandomNumberGenerator()];
}
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
@EntryPoint()
operation SampleRandomNumber() : Int {
let max = 50;
Message($"Sampling a random number between 0 and {max}: ");
return SampleRandomNumberInRange(max);
}
}
```

The program runs the operation or function marked with the `@EntryPoint()`

attribute on the default full state simulator.

Copy and paste the full code sample into the Copilot in Azure Quantum, select the number of shots to run, and click **Run**. The results are displayed in the histogram and in the **Results** fields.

Note

A project file is not necessary to run the Q# code in the Copilot in Azure Quantum. Likewise, installing the QDK is not necessary, as the copilot already runs the latest QDK.

Note

This code snippet does not currently run on any available Azure Quantum hardware targets, as the callable `ResultArrayAsInt`

requires a QPU with full computation profile.

## Next steps

Explore other Q# tutorials:

- Explore entanglement with Q# shows how to write a Q# program that manipulates and measures qubits and demonstrates the effects of superposition and entanglement.
- Implement Grover's search algorithm in Q# shows how to write a Q# program that uses Grover's search algorithm to solve a graph coloring problem.
- Write and simulate qubit-level programs in Q# explores how to write a Q# program that directly addresses specific qubits.

## Feedback

Submit and view feedback for