大数のモジュールの計算方法は?
質問
5^55モジュラス221のモジュラスを電卓をあまり使わずに計算する方法を教えてください。
暗号技術における数論には、このようなことを計算する簡単な原理があるのでしょう。
どのように解決するのですか?
さて、では計算したいのは
a^b mod m
. まず、素朴なアプローチをとり、次にそれをどのように洗練させるかを見てみましょう。
まず、縮小して
a mod m
. つまり、数字を見つける
a1
ということで
0 <= a1 < m
となり
a = a1 mod m
. そして、ループで繰り返し
a1
を掛けて、また減らして
mod m
. このように、擬似コードでは
a1 = a reduced mod m
p = 1
for(int i = 1; i <= b; i++) {
p *= a1
p = p reduced mod m
}
このようにすることで
m^2
. ここがポイントです。よりも大きな数字を避ける理由は
m^2
は、各ステップで
0 <= p < m
と
0 <= a1 < m
.
例として、次のように計算してみましょう。
5^55 mod 221
. まず
5
は既に縮小されて
mod 221
.
-
1 * 5 = 5 mod 221
-
5 * 5 = 25 mod 221
-
25 * 5 = 125 mod 221
-
125 * 5 = 183 mod 221
-
183 * 5 = 31 mod 221
-
31 * 5 = 155 mod 221
-
155 * 5 = 112 mod 221
-
112 * 5 = 118 mod 221
-
118 * 5 = 148 mod 221
-
148 * 5 = 77 mod 221
-
77 * 5 = 164 mod 221
-
164 * 5 = 157 mod 221
-
157 * 5 = 122 mod 221
-
122 * 5 = 168 mod 221
-
168 * 5 = 177 mod 221
-
177 * 5 = 1 mod 221
-
1 * 5 = 5 mod 221
-
5 * 5 = 25 mod 221
-
25 * 5 = 125 mod 221
-
125 * 5 = 183 mod 221
-
183 * 5 = 31 mod 221
-
31 * 5 = 155 mod 221
-
155 * 5 = 112 mod 221
-
112 * 5 = 118 mod 221
-
118 * 5 = 148 mod 221
-
148 * 5 = 77 mod 221
-
77 * 5 = 164 mod 221
-
164 * 5 = 157 mod 221
-
157 * 5 = 122 mod 221
-
122 * 5 = 168 mod 221
-
168 * 5 = 177 mod 221
-
177 * 5 = 1 mod 221
-
1 * 5 = 5 mod 221
-
5 * 5 = 25 mod 221
-
25 * 5 = 125 mod 221
-
125 * 5 = 183 mod 221
-
183 * 5 = 31 mod 221
-
31 * 5 = 155 mod 221
-
155 * 5 = 112 mod 221
-
112 * 5 = 118 mod 221
-
118 * 5 = 148 mod 221
-
148 * 5 = 77 mod 221
-
77 * 5 = 164 mod 221
-
164 * 5 = 157 mod 221
-
157 * 5 = 122 mod 221
-
122 * 5 = 168 mod 221
-
168 * 5 = 177 mod 221
-
177 * 5 = 1 mod 221
-
1 * 5 = 5 mod 221
-
5 * 5 = 25 mod 221
-
25 * 5 = 125 mod 221
-
125 * 5 = 183 mod 221
-
183 * 5 = 31 mod 221
-
31 * 5 = 155 mod 221
-
155 * 5 = 112 mod 221
したがって
5^55 = 112 mod 221
.
さて、これを改善するために
二乗による指数計算
これは有名なトリックで、指数を減らして
log b
の代わりに
b
. 上で説明したアルゴリズム、二乗改善による指数化では、最終的に
右から左への2進法
.
a1 = a reduced mod m
p = 1
while (b > 0) {
if (b is odd) {
p *= a1
p = p reduced mod m
}
b /= 2
a1 = (a1 * a1) reduced mod m
}
したがって、2進数で55=110111なので
-
1 * (5^1 mod 221) = 5 mod 221
-
5 * (5^2 mod 221) = 125 mod 221
-
125 * (5^4 mod 221) = 112 mod 221
-
112 * (5^16 mod 221) = 112 mod 221
-
112 * (5^32 mod 221) = 112 mod 221
したがって、答えは
5^55 = 112 mod 221
. これがうまくいく理由は
55 = 1 + 2 + 4 + 16 + 32
ということで
5^55 = 5^(1 + 2 + 4 + 16 + 32) mod 221
= 5^1 * 5^2 * 5^4 * 5^16 * 5^32 mod 221
= 5 * 25 * 183 * 1 * 1 mod 221
= 22875 mod 221
= 112 mod 221
を計算するステップでは
5^1 mod 221
,
5^2 mod 221
などがあります。
5^(2^k)
=
5^(2^(k-1)) * 5^(2^(k-1))
なぜなら
2^k = 2^(k-1) + 2^(k-1)
を計算することができるため、まず
5^1
を計算し
mod 221
を、次にこれを二乗して
mod 221
を求めます。
5^2 mod 221
など。
上記のアルゴリズムはこの考えを形式化したものです。
関連
-
[解決済み】Rubyで数値の配列の合計を出すには?
-
[解決済み] 整数の平方根が整数であるかどうかを判断する最速の方法
-
[解決済み] NaN値をチェックするにはどうすればよいですか?
-
[解決済み] 簡単な面接問題が難しくなった:1~100の数字が与えられたとき、ちょうどk個の数字が欠けていることを見つけなさい。
-
[解決済み] JavaScriptで整数の除算を行い、余りを別途取得する方法は?
-
[解決済み] 2つの緯度経度点間の距離を計算する?(ハバーシンの公式)
-
[解決済み】関数f(f(n))を設計する == -n
-
[解決済み】「エントロピーと情報利得」って何?
-
[解決済み】JavaScriptの%(modulo)は負の数に対して負の結果を与える
-
[解決済み】なぜ10進数は2進数で正確に表現できないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Mathematica の行列の対角化
-
[解決済み] 回帰式 T(n) = 2T(n/2) + Θ(1) を代入して解きます。
-
[解決済み] LaTeX: 数学モードで3行をスタックする
-
[解決済み] Mathematica の行列対角化
-
[解決済み] バイトからメガバイトへの変換
-
[解決済み] 標準的な正規化ではなく、なぜソフトマックスを使用するのですか?
-
[解決済み] バックプロパゲーション・ニューラルネットワークで非線形活性化関数を使用しなければならない理由は何ですか?[クローズド]
-
[解決済み] atan2()を0-360度へマップする方法
-
[解決済み] clojureで数字を割ると分数が出ますが、小数を出すにはどうしたらいいですか?
-
LaTeXを使ったreStructuredTextの数学