C++でランダムな16進数(Hex Byte)を生成する方法【rand()・itoa()活用】
C++には、指定した範囲内の乱数を取得できるrand()関数が標準で用意されています。本記事では、このrand()と、整数を任意の基数の文字列に変換できるitoa()関数を組み合わせて、「ランダムな16進数(Hex Byte)」を生成するプログラムを作成します。まずは使用する2つの関数の概要から確認していきましょう。
rand()関数とは
rand()は<stdlib.h>ヘッダーで宣言されている事前定義済みの関数で、擬似乱数(整数)を生成します。単体では0以上RAND_MAX以下の値を返すため、実際には次のように剰余演算と組み合わせて、目的の範囲に収まる乱数を作ります。
new_n = ((rand() % (max_n + 1 - min_n)) + min_n);
ここでmin_nは乱数の下限、max_nは上限です。この式により、min_n以上max_n以下の範囲で乱数が得られます。たとえば下限を1、上限を100と設定すれば、1〜100のいずれかの整数が返ります。
itoa()関数とは
itoa()は、10進数などの整数値を、指定した基数に基づくヌル終端文字列へ変換する関数です。変換結果は、ユーザーが定義したchar型配列に格納されます。第3引数に16を渡せば、整数を16進数表記の文字列に変換できます。
注意:itoa()はISO標準のC/C++には含まれていない非標準の関数です。Visual C++やMinGWなど多くの処理系で利用できますが、移植性を重視する場合は後述の代替手段も検討してください。
構文
itoa(new_n, Hexadec_n, 16);
- new_n:変換元となるランダムな整数値
- Hexadec_n:変換結果を格納するユーザー定義のchar型配列
- 16:基数(16進数を意味する)
つまりこの呼び出しによって、10進数の整数が16進数の文字列へと変換されます。
アルゴリズム
- 整数型の変数max_nを宣言し、100で初期化する。
- 整数型の変数min_nを宣言し、1で初期化する。
- char型の配列Hexadec_nを宣言する。
- 整数型の変数new_nとiを宣言する。
- iが0から5未満の間、以下の処理を繰り返す。
・new_n = ((rand() % (max_n + 1 - min_n)) + min_n) を計算する
・「The random number is:」とnew_nの値を出力する
・itoa(new_n, Hexadec_n, 16)を呼び出し、10進数を16進数へ変換する
・「Equivalent Hex Byte:」とHexadec_nの値を出力する
サンプルコード
#include <iostream>
#include <conio.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char **argv) {
int max_n = 100;
int min_n = 1;
char Hexadec_n[100];
int new_n;
int i;
for (i = 0; i < 5; i++) {
new_n = ((rand() % (max_n + 1 - min_n)) + min_n);
// rand()がランダムな10進数を返す
cout << "The random number is: " << new_n;
itoa(new_n, Hexadec_n, 16); // 10進数を16進数に変換
cout << "\nEquivalent Hex Byte: "
<< Hexadec_n << endl << "\n";
}
return 0;
}
実行結果
The random number is: 42 Equivalent Hex Byte: 2a The random number is: 68 Equivalent Hex Byte: 44 The random number is: 35 Equivalent Hex Byte: 23 The random number is: 1 Equivalent Hex Byte: 1 The random number is: 70 Equivalent Hex Byte: 46
※出力される値は実行ごとに変わります。ただし、srand()でシードを初期化しない場合、rand()は毎回同じ乱数列を返すため、プログラムを実行するたびに同じ結果になる点に注意してください。
補足:より安全で移植性の高い書き方
実運用では、次の2点を意識するとよいでしょう。
- srand()によるシード初期化:プログラム開始時にsrand(time(NULL))を一度呼び出せば、実行のたびに異なる乱数列を得られます(<ctime>のインクルードが必要です)。
- 標準機能での16進変換:itoa()は非標準のため、GCCやClangなどでも確実に動作させたい場合は、snprintf()やstd::ostringstreamとstd::hexを利用する方法がおすすめです。
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <sstream>
int main() {
std::srand(static_cast<unsigned>(std::time(nullptr)));
for (int i = 0; i < 5; ++i) {
int new_n = std::rand() % 100 + 1; // 1〜100の乱数
std::ostringstream ss;
ss << std::hex << new_n; // 16進数文字列へ変換
std::cout << "The random number is: " << new_n
<< "\nEquivalent Hex Byte: " << ss.str()
<< "\n\n";
}
return 0;
}
なお、A〜Fを大文字で表示したい場合は、std::uppercaseマニピュレータを使用するか、変換後に各文字へstd::toupper()を適用してください。用途に応じてこれらの手法を使い分けることで、可搬性の高い乱数生成処理を実現できます。
-
C++で16進数を10進数に変換するプログラムの作成方法
16進数が入力として与えられたとき、その16進数を10進数に変換するのが本記事のテーマです。 コンピュータにおける16進数は基数16で表現され、10進数は基数10で表現されます。10進数では0〜9の数字のみを使用しますが、16進数では0〜15までの値を扱うことができ、10以上の値はそれぞれA(10)、B(11)、C(12)、D(13)、E(14)、F(15)という英字で表されます。 16進数から10進数への変換手順 16進数を10進数に変換するには、以下の手順に従います。 右端の桁から順に数字を取り出し、0から始まるべき乗を掛けていきます。指数は「桁数 − 1」になるまで1ずつ増やします。
-
C++で10進数を16進数に変換するプログラムの作り方
10進数の数値が入力として与えられたとき、その数値を16進数に変換するのが本記事の目的です。 コンピュータの世界では、16進数は基数16で表現され、10進数は基数10で表現されます。10進数は0〜9の値を使って表されるのに対し、16進数は0〜15の数字を持ちます。そのうち10は「A」、11は「B」、12は「C」、13は「D」、14は「E」、15は「F」として表されます。 10進数から16進数への変換手順 10進数を16進数に変換するには、以下の手順に従います。 まず、与えられた数値を変換先の基数で割ります。たとえば、6789を16進数に変換する場合、基数である16で6789を割り、商を求め