연습 - 양자 난수 생성기 만들기
이 섹션에서는 양자 난수 생성기의 두 번째 단계를 구현합니다. 즉, 여러 개의 임의 비트를 결합하여 유효하고 안전한 암호로 사용할 수 있는 더 큰 숫자를 생성합니다. 이 단계는 이미 만든 임의 비트 생성기를 기반으로 합니다. 이 단계를 위해 일부 클래식 코드를 작성해야 합니다.
먼저, 클래식 코드가 Q#과 어떻게 결합되는지 살펴보겠습니다.
Q#에서 클래식 코드를 작성할 수 있나요?
예, 할 수 있습니다. 양자 컴퓨터는 특수한 작업을 수행합니다. 대부분의 작업은 일반 컴퓨터로 충분하기 때문에 모든 작업에 양자 컴퓨터를 사용하지는 않습니다.
GPU(그래픽 처리 장치) 또는 기타 특수 하드웨어와 마찬가지로 양자 컴퓨터는 가장 적합한 작업에 사용해야 합니다. 여기서는 순수 임의 비트를 생성하려고 합니다.
이것이 Q#에서도 이미 알고 있는 프로그래밍 언어와 유사한 클래식 코드를 작성할 수 있는 이유입니다.
Q# 기능을 사용하여 전체 난수 생성기를 빌드하는 방법을 알아보겠습니다.
난수 생성기 논리 정의
계속하기 전에 임의 비트 생성기가 있는 경우 난수 생성기 논리를 간략하게 살펴보겠습니다.
max
를 생성하려는 최대 수로 정의합니다.- 생성해야 하는 임의 비트의 수를 정의합니다.
이를 위해 최대 정수
max
를 표현하는 데 필요한 비트 수nBits
를 계산합니다. - 길이가
nBits
인 임의 비트 문자열을 생성합니다. - 비트 문자열이
max
보다 큰 숫자를 나타내는 경우 3단계로 돌아갑니다. - 그렇지 않으면 프로세스가 완료된 것입니다. 생성된 숫자를 정수로 반환합니다.
예를 들어 max
를 12로 설정하겠습니다. 여기서 12는 보안 암호로 사용하려는 가장 큰 숫자입니다.
0에서 12 사이의 숫자를 나타내려면 ${\lfloor ln(12) / ln(2) + 1 \rfloor}$, 즉 4비트가 필요합니다. (간결한 설명을 위해 이 수식을 유도하는 방법은 생략합니다.)
${13_{\ decimal}}$에 해당하는 비트 문자열 ${1101_{\ binary}}$를 생성한다고 가정하겠습니다. 13은 12보다 크므로 프로세스를 반복합니다.
다음으로 ${6_{\ decimal}}$에 해당하는 비트 문자열 ${0110_{\ binary}}$를 생성합니다. 6은 12보다 작으므로 프로세스는 완료된 것입니다.
QRNG는 숫자 6을 암호로 반환합니다. 적은 수의 값은 가능한 모든 암호를 시도하여 쉽게 해독할 수 있기 때문에 실제로는 더 큰 숫자를 최댓값으로 설정합니다. 실제로 암호 추측 또는 해독을 어렵게 하기 위해 ASCII 코드를 사용하여 이진을 텍스트로 변환하고 숫자, 기호, 대/소문자를 사용하여 암호를 생성할 수 있습니다.
이제 암호가 완전히 무작위로 설정됨을 확신할 수 있습니다. 우주선 데이터 및 해당 기능은 최고 수준의 보안 표준으로 보호됩니다.
이제 이 논리를 사용하여 전체 난수 생성기를 빌드할 준비가 되었습니다.
SampleRandomNumberInRange 작업 만들기
여기서는 QuantumRNG 프로젝트를 확장하여 더 큰 난수를 생성합니다.
필요한 라이브러리 추가
전체 난수 생성기의 경우 두 개의 추가 라이브러리 Microsoft.Quantum.Math
및 Microsoft.Quantum.Convert
를 포함해야 합니다. 다음과 같이 Program.qs에 다음 open
지시문을 추가합니다.
namespace QuantumRNG {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
@EntryPoint()
operation GenerateRandomBit() : 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 M(q);
}
}
작업 정의
여기에서 SampleRandomNumberInRange
작업을 정의합니다. 이 작업은 GenerateRandomBit
작업을 반복적으로 호출하여 비트 문자열을 생성합니다.
다음과 같이 Program.qs를 수정합니다.
namespace QuantumRNG {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
operation GenerateRandomBit() : 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 M(q);
}
operation SampleRandomNumberInRange(max : Int) : Int {
mutable output = 0;
repeat {
mutable bits = [];
for idxBit in 1..BitSizeI(max) {
set bits += [GenerateRandomBit()];
}
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
}
잠시 새 코드를 검토해 보겠습니다.
max
까지 정수를 표현하는 데 필요한 비트 수를 계산해야 함을 기억할 것입니다. Microsoft.Quantum.Math
라이브러리가 이를 계산하는 BitSizeI 함수를 제공합니다.
SampleRandomNumberInRange
작업은 repeat
루프를 사용하여 max
보다 작거나 같은 값을 생성할 때까지 난수를 생성합니다.
repeat
내의 for
루프는 다른 프로그래밍 언어의 for
루프와 동일하게 작용합니다.
이 예제에서 output
및 bits
는 변경 가능한 변수입니다. 변경 가능한 변수는 계산 중에 변경될 수 있는 변수입니다. set
지시문을 사용하여 변경 가능한 변수의 값을 변경할 수 있습니다.
ResultArrayAsInt 함수는 Microsoft.Quantum.Convert
라이브러리가 제공합니다. 이 함수는 비트 문자열을 양의 정수로 변환합니다.
진입점 정의
이제 프로그램이 난수를 생성할 수 있습니다. 여기에서 프로그램 진입점을 정의합니다.
다음과 같이 Program.qs를 수정합니다.
namespace QuantumRNG {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
operation GenerateRandomBit() : 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 M(q);
}
operation SampleRandomNumberInRange(max : Int) : Int {
mutable output = 0;
repeat {
mutable bits = [];
for idxBit in 1..BitSizeI(max) {
set bits += [GenerateRandomBit()];
}
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);
}
}
let
지시문은 계산 도중 변경되지 않는 변수를 선언합니다. 학습 목적을 위해 여기서는 최대 값을 50으로 정의합니다.
참고
이 코드 조각은 현재 사용 가능한 Azure Quantum 하드웨어 대상에서는 실행되지 않습니다. 호출 가능 ResultArrayAsInt
에는 전체 계산 프로필이 있는 QPU가 필요하기 때문입니다
이러한 알림이 없는 학습 모듈 코드는 현재 하드웨어 대상에서 실행 가능합니다.
프로그램 실행
새 난수 생성기를 사용해 보겠습니다.
Visual Studio Code의 통합 터미널에서
dotnet run
을 실행합니다.dotnet run
샘플 출력은 다음과 같습니다.
Sampling a random number between 0 and 50: 42
계산에서 50보다 큰 숫자를 생성할 수 있습니다. 그러나
repeat
루프는 50 이하의 숫자를 생성할 때까지 작업을 다시 시도합니다.선택적 단계로, 다음과 같이 프로그램을 다시 실행합니다.
dotnet run --no-build
(코드를 변경하는 경우 프로그램을 다시 빌드하기 위해
--no-build
인수를 생략해야 합니다.)샘플 출력은 다음과 같습니다.
Sampling a random number between 0 and 50: 10
축하합니다! 이제 고전 논리를 Q#과 결합하여 양자 난수 생성기를 만드는 방법을 알았습니다.
보너스 연습
생성된 난수를 0이 아니라 최소 수 min
보다 크게 요구하도록 프로그램을 수정합니다.
다음 단원에서는 일반적인 구조 Q # 프로그램과 양자 컴퓨팅의 기본 구성 요소에 대해 자세히 알아봅니다.