プレゼント企画の当選者を公正に選び、抽選過程を公開する方法
当選者を公正に選ぶには、セキュリティ向けに作られた乱数生成を使い、すべての応募者に同じ当選確率を与え、結果を後から誰でも確認できるようにします。単純な抽選ツールで不公平が生まれる原因は、主に二つです。乱数の元になる値が弱いこと、そして剰余(モジュロ)計算による小さなずれ、いわゆるモジュロバイアスです。どちらも解決できます。応募者リストと抽選の記録を公開すれば、当選者が恣意的に選ばれていないことを最もよく示せます。
ランダム抽選公平に当選者を選びたい無料で使う真の乱数と擬似乱数
真の乱数は、電子回路の雑音のような物理現象から予測できなさを得ます。一方、擬似乱数生成は計算式です。種(シード)と呼ばれる初期値から決まった手順で計算を進め、ランダムに見える数列を作ります。数列は種によって完全に決まるため、種と計算式を知っている人はすべての数値を予測できます。
多くのソフトウェアは擬似乱数生成を使っており、プレイリストのシャッフルやゲームのステージ生成ならそれで十分です。ただし当選にかかわる抽選では、結果を予測されたり操作されたりしないかどうかが問題になります。高速でも予測可能な生成器は、この用途には不向きです。
ブラウザの暗号学的乱数生成を使う
JavaScriptのMath.random()は高速な擬似乱数生成です。公式ドキュメントでも暗号用途には向かないとされており、プレゼント抽選はセキュリティに関わる判断が必要な場面です。Web Crypto APIのcrypto.getRandomValues()は、OSの暗号学的乱数源から取った値で配列を埋めます。こちらを使うべきです。ランダム抽選は、コイン投げやサイコロを含むすべての抽選にこの関数を使っています。どの乱数を使うかを示さないツールは信頼しにくいので、使う前に確認しましょう。
モジュロバイアスを一例で理解する
0から255までの整数、つまり1バイトの乱数が得られ、3つの候補から1つを選びたいとします。簡単な方法は、3で割った余りを使うことです。一見公平に見えますが、256は3のグループに均等に分けられません。
- 0、3、6……と255まで、余りが0になる値は86個あります。
- 余りが1になる値は85個、余りが2になる値も85個です。
その結果、候補0は256回中86回、約33.6%で出てきます。一方、候補1と2はそれぞれ85回、約33.2%です。差はわずかですが実際に存在し、候補の数が乱数の範囲に比べて大きくなるほど広がります。
解決策は棄却サンプリングです。値を一つ取り、それが割り切れない余りの部分に入ったら、引き直します。バイト値の例では、255を捨てて0から254だけを採用します。これは3で均等に割れる範囲です。32ビットの乱数なら、余る値は約43億分の1程度なので、プレゼント抽選では無視できるほど小さなバイアスです。ただし同じ誤りは範囲が狭くなるほど大きくなるため、丁寧な抽選ツールは棄却サンプリングを使うべきです。
重複なしで複数人を選ぶ
複数の当選者を選ぶ場合、乱数で添字を3回選ぶと、同じ応募者が2回当選する可能性があります。重複を防ぐ方法は次の二つです。
- 当選者が決まるたびにリストから外し、残りから引き直す。
- リスト全体をフィッシャー–イェーツ法で一度シャッフルし、先頭から当選者を取る。
フィッシャー–イェーツ法は、リストの末尾から順に各位置を、その位置以前のランダムな位置と入れ替えていきます。乱数の選び方が公平であれば、すべての並び順が等しい確率で現れます。手順が短く、よく知られており、応募者にも説明しやすい方法です。ランダム抽選の「当選者を除外」と「重複なし」の設定は、この二つの方法に対応しています。
抽選を検証できるようにする
公正な抽選とは、誰でも検証できる抽選です。抽選の前に次のことを行いましょう。
- 応募者を番号付きリストとして公開し、参加資格のルールも併せて示す。
- そのリストのSHA-256の指紋を公開する。SHA-256に対応したツールなら誰でも作れます。たとえばハッシュ生成で作れます。指紋は応募者が1件でも変わると全く別の値になるため、後からリストをこっそり書き換えることができなくなります。同じ確認方法はダウンロードファイルの検証にも使えます。手順はダウンロードしたファイルのSHA-256チェックサムを確認する方法で解説しています。
抽選中と抽選後には次のことを行いましょう。
- 抽選ツールを起動した時点から、表示された結果までを画面録画する。
- 当選番号を入れた最終リストを公開し、誰でも指紋を再計算して変更されていないことを確認できるようにする。
- 当選者の選び方を説明する。たとえば「OSの暗号学的乱数源を使うブラウザ上の抽選ツールで選出」のように書きます。
プレゼント抽選のルールは販売・配信プラットフォームごとに異なり、お住まいの地域によっては法的な要件が課される場合もあります。実施する前に、各プラットフォームの販促ルールと現地の法律を確認してください。本記事は一般的な案内であり、法律上の助言ではありません。準備ができたら、ランダム抽選で当選者を選びましょう。
fixmintでの手順
- 名前を選び、名前(1行に1つ)に応募者を貼り付けます。
- 当選者数に賞品の数を入力します。同じ人が2回当選しないよう、当選者をリストから除外にチェックを入れます。
- 番号で抽選する場合は、番号を選び、最小と最大を設定します。各番号が1回しか当選しないようにする場合は、重複なしにチェックを入れます。
- 開始時点から画面録画を始めた状態で、当選者を抽選を押します。
- 番号付きの応募者リスト、SHA-256の指紋、当選した応募者、そして抽選ツールの使い方を公開します。
よくある質問
Math.random()はプレゼント抽選に使ってもいいですか?
ゲームやシャッフルには問題ありませんが、結果を検証される抽選には向いていません。出力は予測できてしまうため、暗号学的な乱数源を使いましょう。
乱数を応募者数で割った余りで選ぶのではだめですか?
範囲が均等に割り切れない場合、余りの値が偏るため、一部の応募者が選ばれやすくなります。棄却サンプリングを使えばこのバイアスを取り除けます。
一度の抽選で複数の当選者を選べますか?
はい、選べます。次の当選者を決めるたびにその人を除外するか、一度シャッフルして上位の応募者を取ります。どちらの方法でも、同じ応募者が2回当選することはありません。
英語原文をもとに、AIの支援を受けて翻訳しています。
コメント
まだコメントはありません。最初のコメントを書いてみましょう。


