【Python】 FastAPIでBearer認証を実装する

最近ふざけた内容が多かったので、少し真面目に。 背景 Nuxt.js + FastAPI でツールを作成している。認証周りで @nuxtjs/auth を使用したところ、スクラッチでAPIを作成している場合にはJWTを使った認証が標準っぽかったので、API側もそれに合わせた。 ソースコード umentu/fastapi_bearer 解説 ほぼJWTの解説になってしまっているけど、②と⑥の部分をFastAPIで実装している。以下すべてのソースコードはGitHubの方にみてもらうとして、FastAPIの部分だけを抜粋すると次の2つの関数のみ。 @app.post(‘/get_token’, response_model=models.GetTokenResponseModel) def get_token(m: models.GetTokenModel):     user = search_user_for_token(m.userName, m.password)     if not user:         raise HTTPException(             status_code=HTTP_401_UNAUTHORIZED,             detail=’ユーザー名/パスワードが違います’,             headers={‘WWW-Authenticate’: ‘Bearer’}         )     # トークンを作成     token_expires = timedelta(minutes=TOKEN_EXPIRE_MINUTES)     access_token = create_access_token(         data={‘userName’: user[‘userName’]},         expires_delta=token_expires     )     return {‘token’: access_token, ‘token_type’: ‘bearer’} @app.post(‘/get_user’, response_model=models.GetUserResponseModel) async def get_user(user_data: models.GetUserResponseModel = Depends(get_user_data)):     return JSONResponse({‘user’: user_data}) /get_token へアクセスするとユーザー情報を暗号化してトークンを作成し返す。返されたトークンを /get_user に投げるとトークンを復号化してユーザー情報を取得し、それを元にユーザー情報を返す。ただこれだけ。クライアント側は、トークンをLocalStorageに保存すればいい。 テスト

コマンド打ち間違えた!!!f○ck!!!! を補完してくれる「thefuck」

Twitterで面白いツールを見かけたので。 @nvbn/thefuck 名前的にアレだけど、便利。どういうものかというと、コマンドの打ち間違えを認知して「このコマンドじゃね?」と提案してくれるもの。 インストール Macの場合 brew install thefuck Ubuntuの場合 sudo apt update sudo apt install python3-dev python3-pip python3-setuptools sudo pip3 install thefuck Python環境があれば、これでもいける。 pip install thefuck テスト 一般的なコマンドはおおよそフォローしてくれるけど、自分で入れたツールは補完してくれない模様。とはいえ、「Fuck!!!」と思った時にそのまま打てるのはいいね!(よくない)

【pytest】なんかpytestのドキュメントどおりやるとtestが通らない

pytestを改めてしっかり使おうとドキュメントをみたところ、パスの設定間違ってない?というか、ドキュメントどおりにやるとモジュールのパスが通らなかった。 Pytest – Good Integration Practice 次のように指定するように書いてある。 | – setup.py| – mypkg/ | – __init__.py | – app.py | – view.py | – tests/ | | – mypkg | – test_app.py | – test_view.py しかし、このように実行すると次のようなエラーが。 __________________ ERROR collecting tests/test_app.py ____________________ ImportError while importing test module ‘project_dir/tests/test_app.py’. Hint: make sure your test modules/packages have valid Python names. Traceback: tests/test_app.py:10: in <module> from mypkg import app E ModuleNotFoundError: No module named ‘mypkg’ エラーの原因としては……なんだろう。ただ解決方法は次のとおり。 | – setup.py | – mypkg/ | – app.py | – view.py | – tests/ | – __init__.py | – mypkg | – test_app.py | – test_view.py pkg配下の__init__.pyを外し、tests配下に__init__.pyを置くとテストが通る。ただ、mypkg配下に__init__.pyを置きたいときはどうするんだろ。

【Nuxt.js】@nuxtjs/dotenvと@nuxtjs/axiosでBaseURLの設定が必要ない話

ソース探ってたら、axiosのBaseURLの設定について色々間違った情報が出回っているようで。 not BaseUrl, but BaseURL BaseURLを次のように説明しているサイトが散見された。 /* nuxt.config.js */ // dotenvを使っている場合 require(‘dotenv’).config(); export default { // … axios: { baseUrl: process.env.baseUrl } } Javascriptはキャメルケースで書くから間違えやすいんだけど、とはいえ間違った情報が多かった そもそもbaseURLが必要ない ソースを読んだところ、環境変数で指定すればいいことに気づいた。 nuxt-community/axios-module API_PORTやPORT、API_HOSTやHOSTを設定しておけばbaseURLの設定すらいらなかった。 // .env API_POST=”443″ API_HOST=”ドメイン”

まだPythonでパス指定する時にosライブラリを使って疲弊してるの?

まだ割と新しいソースを観ると、凄い長いパスの指定の仕方をしているのを見かけるので。 疲弊する書き方 ソースがあるディレクトリ、親ディレクトリ、ファイルパスを指定する場合の昔ながらの書き方は次の通り。 # coding: utf-8 import os # ソースがあるディレクトリ PROJECT_DIR = os.path.dirname(os.path.abspath(__file__)) # 親ディレクトリ PARENT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) いーーーってなる。もしくは次のようにも書けるが。 # coding: utf-8 from os.path import dirname, absname, join # ソースがあるディレクトリ PROJECT_DIR = dirname(absname(__file__)) # 親ディレクトリ PARENT_DIR = dirname(dirname(abspath(__file__))) # ファイルパス FILE_PATH = join(dirname(dirname(abspath(__file__))), ‘ファイル名’) absnameはともかく、dirnameとjoinはなんか名前汚している感が半端なくて嫌。 pathlibを使おう もう、pathlib使お?凄い楽だし。 # coding: utf-8 from pathlib import Path # ソースがあるディレクトリ PROJECT_DIR = Path().cwd() # 親ディレクトリ PARENT_DIR = Path().cwd().parent # ファイルパス FILE_PATH = Path().cwd().parent / ‘ファイル名’ ……すごくない?上2つは当然凄いけど、ファイルパスを / 演算子に割り当てたの、天才すぎない?考えた人、ホント天才。 というわけで疲弊しないために、pathlibを使おう!

最強のFish Shell環境 – Fisher + ghq + peco で最強のgit環境

0. 前回まで ぼくのかんがえたさいきょうのたーみなるかんきょう 1. ざっくり解説 Fisher fisher は fish shellのプラグインで、fish shellのプラグイン管理ツール ghq ghqはgitを一つのディレクトリ配下で管理するツール peco インクリメンタルサーチ(入力に応じて候補を絞り込む検索方法)をターミナルで実現できるツール fish-ghq Ctrl + gで ghq を起動できるプラグイン oh-my-fish/plugin-peco fish shell用の peco プラグイン 2. 環境構築 fisher curl https://git.io/fisher –create-dirs -sLo ~/.config/fish/functions/fisher.fish ghq brew install ghq # 必要であれば、以下の設定で管理ディレクトリを設定(デフォルトは$HOME/.ghq) git config –global ghq.root 対象ディレクトリ peco brew install peco fish-ghq fisher add decors/fish-ghq echo ‘set GHQ_SELECTOR peco’ >> $HOME/.config/fish/config.fish exec fish oh-my-fish/plugin-peco fisher add oh-my-fish/plugin-peco 動作チェック

VS CodeのPythonプラグインの最新版でComannd not foundが発生する模様

よかったらこれも読んでね! VS Codeでインタープリターを切り替えようとしたところ Command ‘python.setInterpreter’ not found というエラーが発生。 というか、python関連のコマンドが全部使えなくなってる! 調べたところ、python-4.11881というバージョンでエラーは発生している模様。そのため、一つ前のバージョンに切り替えると正常にコマンドが実行できた。 手順 1.プラグイン管理画面を開く 2. pythonプラグインを表示し、別のバージョンをインストールを選択 3. 一つ前の 2019.3.7558うぃを選択 4. VS Code再読み込み

ぼくのかんがえたさいきょうのVS Code 1

VS Code熱いので。 プラグインの入れ方 コマンドパレットの表示の仕方 Windows: Ctrl + Shift + PMac: Command + Shift + PLinux: Ctrl + Shift + P Setting Sync Settings Sync 絶対に最初に入れておいた方がいいプラグイン。VS Codeの設定をGithubのgistで同期することができる。一度設定しておけば、他のPCでVS Codeを使いたいときに一気に同じ環境を構築できる。 インストール方法は、少し面倒。 1. GitHubにアクセス VS Code側の設定 Settings Syncをインストール コマンドパレットを表示し、Syncと入力してUpload Settingsと選択。 先程Githubで取得したトークンを入力 これでアップロードされる。更におまけとして、自動で同期させたい場合は、次の設定を行う。 Material Icon Theme Material Icon Theme ファイルの種類のアイコンをマテリアルデザインのアイコンに。みやすい。 indent-rainbow indent-rainbow インデントを虹色で表現してくれる。Pythonだと必須。デフォルトは色が淡い。 ので、settings.pyを書き換えて色を変更した。 以下を追記。 VS Codeを再起動すると反映される。 Japanese Language Pack for Visual Studio Code Japanese Language Pack for Visual Studio Code 日本語化。必要であれば。 Bracket Pair Colorizer 2 Bracket Pair Colorizer 2 括弧を多様する言語を使用する場合はほしい。 Regex Previewer Regex Previewer 正規表現 VSNotes VSNotes VSNotesはマークダウン式のメモをタグ付けして保存してくれるとても便利ツール。コマンドパレットを開き、Create a New Noteを選択するとマークダウンファイルが設定したディレクトリに作成される。ディレクトリをGoogle DriveやDropboxなどのディレクトリを指定すると他のPCでも共有できる。 ちなみにマークダウンで書いたら、 Windows/Linux: Ctrl + K -> V 、Mac: Command + K -> V でプレビューが表示されるよ。 Markdown PDF Markdown PDF 結構驚きのツールだった。マークダウンで記述したものをPDF/HTMLに変換できるというもの。 Output Colorizer/Log File…

ハッカー(エンジニア)は黒い画面で何をやっているか

ふと思い立ったので書いてみる。知識のある方に前置きすると、ハッカーはここでは「ITに詳しい人」という意味で使う。いいことをする意味でも、悪いことをする意味でも、である。 イメージ もう映画「Matrix」が公開されて20年。黒い画面上に意味不明な文字列が延々と流れていた。Matrixの主人公は銃弾を避けるイメージが根強いが、仮想世界上では「ネオ」という天才ハッカーという設定がある。そこから、ハッカーは黒い画面を覗き込んでキーボードをカタカタ叩くイメージがついてきた。 その前からハッカーは暗い部屋でパソコンを叩くイメージはあったかもしれない。(ちなみに私の好きな映画「The Internet」はあまり黒い画面は出てこなかった。)彼らは黒い画面で何をしているのか。マウス操作と何が違うのか。 CLI 黒い画面のことをCLI(Command Line Interface)と呼ぶ。Windowsだとコマンドプロンプトであったり、Mac/Linuxだとターミナルと呼ぶが、それらは総称してCLIである。CLIは基本的にはキーボードだけで操作する。今はマウスと組み合わせて操作することもあるが、基本的にマウス操作はあまり使わない。コピペしたいときくらいだろうか。 CLIで何ができるか CLIで何ができるかというと、基本的にはPCの基本操作であれば何でもできる。もちろん、絵を描いたり写真を加工したりすることはとても難しい。難しいという言葉にとどめておいているのは、全くできないわけではないからだ。ただ、マウス操作のほうが圧倒的に楽だ。それはマウス操作するのに最適化されているためであるといえる。 例えば、PCでよくやるファイルの作成、テキストファイルの編集、ファイルのコピーや移動などはすべてCLIでできる。メールの送受信もサイトをみることもできる。Twitterにツイートすることもタイムラインをみることもできる。要するに、普通にPCでしてることができるのだ。 そもそも論はあまり語りたくないが、軽く話すと元々は黒い画面しかなかった。それがウィンドウシステムというシステムの進化により、マウス操作が主流になったのだ。「マウス操作の裏側ではCLIが動いている」と説明する場合もある。 またCLIにはコマンドが用意されていて、コマンドを実行することでファイルをコピーしたり移動したりと、様々な操作を行うことができる。また、スクリプトと呼ばれる実行したいコマンドを並べて書いたファイルを用意することで、いくつかのまとまった処理をスクリプト一つで実行できるのである。例えば、MacでAというフォルダにあるファイル1.txt〜ファイル100.txtというファイルをBというフォルダに移動したいときには次のように書くことでできる。 「100個のファイルを移動するくらい、マウスのほうが速い」と思ったかもしれない。そのとおりである。しかし、「100個のファイルを作成する」となると少しむずかしいかもしれない。それもCLIだと簡単にできる。 これでAフォルダにファイル1.txt〜ファイル100.txtが作成される。100を10000に変えれば10000個のファイルが作成される。様々な活用方法がありそうだ。 今までは操作しているPCのファイルを操作したが、CLIでかなり多くの頻度で使われるのは、サーバーと呼ばれるインターネットなどのネットワークの先にあるファイルをPCのような操作をするときである。SSH(Secure SHell)というシェルを使って通信し、ログインしてサーバー内部の操作を行う。サーバーにはWindowsやMacといったものではない、Linuxというシステムが使われていることが多い。しかし、手元のPCがWindowsやMacであっても、Linuxにログインして操作することが可能である。もちろん、サーバーでもマウス操作できるようにすることができるが、マウス操作をする場合にはサーバーにビデオカードと呼ばれる部品が必要であったり、また画像でやり取りする必要があるため通信速度や通信データ量が膨大に増加する。そのため、サーバーはCLIだけで操作できるようになっている場合が多い。 ハッカーやエンジニアはCLIで何をするか 先程も言ったとおり、CLIはサーバーに接続する目的でよく使われる。ハッカーやエンジニアはサーバーに接続して、サーバーの設定を行ったりプログラムを設置して実行させたりする。 ここでサーバーに関して注意となるが、今まで使っていたサーバーはハードウェア(機器)という意味でのサーバーという意味で使用していた。しかし、サーバーにはソフトウェアとしての意味もあり、例えばWebサーバーというとこのブログのようにサイトを公開する目的で使われ、メールサーバーはメールを送信したり受信したりする目的で使われる。それらはハードウェアとしての意味のサーバーにインストールすることができるのである。 そのため、エンジニアであればWebサーバーやメールサーバーなどの構築のためにCLIを使い、またハッカーであれば公開されているサイトの情報を書き換えたいときにはサーバーにログインしてファイルを書き換えたりするためにCLIを使ったりする。 攻撃時にハッカーがやっていることとは? ハッカーがやっていることといえばハッキングだろう。では、ハッキングとは具体的に何をしているのか?ハッキングしている最中にカタカタキーボードを叩いているのは何をしているのか?少し分類して見てみよう。 侵入 ハッキングといってもいろいろあるが、代表的なものは対象のPCであったりサーバーに侵入することだろう。しかし、侵入とひとえにいっても様々である。例えば、相手のユーザー情報を取得しログインする、というのが一番シンプルだが、相手のユーザー情報やパスワードを調べるのは難しい。セキュリティの弱い会社で、全社員のユーザー名とパスワードの情報を書いたファイルがおかれていたりすればそれを盗むだけでできることもあるが。そのようなときには、ブルートフォースアタックと呼ばれる総当たり攻撃である。ユーザー名やパスワードをランダムに生成し、とにかくログインを試みるのである。もちろん、これは手動ではとてもできない。ランダムにユーザー名やパスワードを生成するプログラムを作成してログインを試行するのだ。つまり、プログラムを作成するときにキーボードをカタカタしている。事前準備というわけだ。そしてそのプログラムを実行するときに「ターン」とエンターキーを押すのである。 もう一つの侵入方法として、プログラムの脆弱性(脆弱性)をつくという方法がある。たびたびWindowsアップデートなどに悩まされている人もいるとは思うが、これはWindowsにある穴、いわゆるセキュリティホールから侵入を試みるのである。プログラミングをやったことがない人にはなかなか実感を持ってもらえないが、プログラミングで書く文字の量は膨大で、ましてやWindowsやMacのように様々なソフトを動かすためのプログラムであれば凄まじい量の文字数となる。物語を長く書けば長く書くほど誤字が増えたり前の設定とのズレが生じたりするように、プログラムもミスが増えてしまう。これがいわゆるバグである。ハッカーはそのようなバグをみつけ、利用できるかどうかを調べる。具体的には、あるメールソフトには受信したコマンドを実行してしまうというプログラムが実行してしまう脆弱性があったとする。ハッカーはその大量にPCのハードディスクを消去してしまうコマンドを含んだメールを大量に送信し、そのソフトを使っている人がメールを受信した瞬間にコマンドを実行し、ハードディスクを消去してしまうのである。これはとても極端な例ではあるが、このようなことは日々起きている。アップデートは重要である。脆弱性は悪意のあるハッカーが先に見つけるかソフトウェア開発者が先に見つけるかよってユーザーの影響が受ける影響は180°変わる。ハッカーはプログラムを入手して解析し、プログラムに脆弱性がないかをとにかく検証する。プログラムに脆弱性がないかどうかをチェックするプログラムを使うかもしれないし、地道に手動で探す場合もあるだろう。映画ではそのシーンが描かれているのかもしれない。 踏み台 これも侵入の一つではあるが、侵入することが目的ではない。ハッカーが直接、自分のパソコンから対象の機器を攻撃すると自分が攻撃したことがバレてしまう。そのため、ある侵入できるPCやサーバーを探し、そこから攻撃を試みるのである。そうすることで自分が攻撃したことを隠すことができる。これが踏み台である。 が、そう簡単でもない。なぜなら、その踏み台となったPCにも当然自分が新入した形跡が残ってしまう。そのため、踏み台をするための踏み台を探す。更にその踏み台を探すための踏み台を探す。更に……とやっていく。それが単なる数珠つなぎになっているとは限らない。ハッカー自身のPCから多数の踏み台サーバーにログインし、それぞれからまた更に多数の踏み台サーバーにログインし、とやっていくと膨大な量の踏み台サーバーが発生し、特定が困難になる。そのように、ある目的を達成するために行う攻撃もあるのである。 方法としては、上で紹介したブルートフォースアタックのような攻撃だったり脆弱性を探したりして踏み台を探す。それらは膨大な作業となるため、自動化するプログラムを作成して侵入を試みるだろう。そうすると侵入を試みるときには、プログラムを実行するだけとなる。画面には、ログインに失敗した、もしくは成功したのような履歴が残るかもしれない。ちなみに以下の画像は私のサーバーにログインを試みたログである。 DoS攻撃/DDoS攻撃 サイトを公開しているWebサーバーなどを稼働させなくすることを目的としたDoS攻撃(Denial of Service attack)やDDoS(Distributed Denial of Service attack)という攻撃がある。DoS攻撃は、あるサーバーに大量のデータを送信することでサーバーが処理しきれなくなりダウンしてしまうことを狙う攻撃である。DDoS攻撃は更に強力で、DoS攻撃を上で紹介した大量の踏み台を使って対象に一気に攻撃を仕掛けることである。今では、DDoS攻撃をDoS攻撃と呼ぶこともある。というのもDDoS攻撃をしないとほぼ影響が出ないからである。Webサーバー以外にもよく攻撃されているのが、スマホなどのゲームで使用しているサーバーである。サーバーがDDoS攻撃を受けたことによりメンテナンスになってしまうことも割とある。(なので、あまり詫び石詫び石といわないでほしいと思っている。) DoS攻撃に関しては、2018年に多くのエンジニアが利用しているGithubというサービスが1.7Tbpsというデータ量の攻撃を受けてサービスが停止した。1.7Tbpsとは、スマホのデータ量で使うギガバイト換算すると、1秒間に210ギガバイト受けた計算となるため、7GBでデータ制限がかかるとすると0.03秒で上限に達してしまうデータ量となる。恐ろしい。 DoS攻撃には綿密な準備が必要だが、実際に実行するときにはプログラムを実行するだけ、のような気がしている。そこまでカタカタカタカタする必要がないかもしれない。 一方、エンジニアは何をしているのか ハッカーから攻撃を受けたエンジニアは何をするのか。ハッカーは今までに話したとおり、準備には時間がかかるが実際に攻撃するときには意外とすることがない。しかしエンジニアは、意外と事件が起こったときにはカタカタすることが多い。こちらも分類してみる。 問題の切り分け サーバーがダウンしたとしても、ハッカーによる攻撃でダウンしたのか故障でダウンしたのかしたかがわからない。また、サーバーが故障したとしても、サーバーのソフトウェア部分がダウンしたのか、機器自体が故障したのか、通信している場合にはネットワーク機器が故障したのかなど、切り分けるところは多数ある。それらを調べるのにはCLIがよく使われる。総合的にチェックするプログラムを用意している場合もあるし、手動で一つ一つの機器に入って調べることもある。常にカタカタカタカタしているのである。 セキュリティのチェック もしサーバーのダウンの原因がハッカーが原因だった場合、発見のタイミングにもよるが基本的にサーバーの機器自体の電源を落とさないといけない。「ハッカーの侵入経路を特定しそこを塞げばいい」と思ってしまうかもしれないが、そうもいかないのだ。というのも侵入された段階で、何らかの悪意のあるプログラムを設置してセキュリティホールを作成していたり、自動的にサーバーの設定を書き換えて侵入しなくてもなんでも自由にできるようにされてしまったりする。そのため、サーバーをダウンさせることが一番の得策となっていまうわけである。もちろん、あとでネットワークを遮断した状態でサーバーを起動し、何が原因で侵入されたかなどを検証する必要があるし、サーバーは同じ設定を複数台に施している場合もあるため、他のサーバーも侵入されないように対策する必要がある。 振り返って ハッカーは事前準備の方が黒い画面をカタカタし、エンジニアは攻撃されているときにカタカタすることが多いというのが私の印象である。もちろん映画では事前準備の風景を重点的に描いてしまっては単なるドキュメンタリーになってしまうし、また攻撃されているエンジニアがサーバーの電源を落とし、機器を交換している風景を描いてもなんの面白みもないだろう。ただ、ちょっとだけ映画と現実のギャップをお伝えしてみたかったのである。 前の会社でデザイナーの人の前でCLIで操作していたときに「CLI触る人って、どこになんのファイルが有るのか全部覚えているんですか?」と聞かれたことがある。私の答えとしては、割と「なんとなく」だ。設定ファイルはどこにあり、プログラムの本体はどこにあり、ログファイルがどこにあるなどは割と決まっている。設定ファイルの中にどこに必要なファイルが書いてあるといったことも覚えてはいる。そのため、大方の操作はCLIの文字情報だけで操作できるのである。 もちろんGUIでのマウス操作は日々便利になっている。WindowsにしろMacにしろ(Linuxにしろ)、バージョンを上げるごとに使いやすくなっていっているというのが私の印象だ。よく「Windows10になって使いづらくなった」というのは単に変わったばかりで慣れていないだけである。本当に変わらない操作がほしいのであれば、CLIをおすすめする。CLIは変わらないよ。

ぼくのかんがえたさいきょうのたーみなるかんきょう

最近、ターミナル環境をガラッと変えてみたので。 iTerm2 iTerm2 いわずとしれた、ターミナルアプリ。他にもいろいろ試したけど、日本語の問題だったりいろいろあったため、やっぱりiTerm2正義! インストール後にフルディスクアクセスを許可する必要がある。 Homebrew Homebrew こちらもパッケージ管理としては必須! motemen/ghq motemen/ghq gitはもちろん使うんだけど、他の人達のリポジトリをちょうだいするときに管理するのに前は自分でスクリプトを組んでいて、ghqの存在を知り驚愕だった。~/.ghq 配下にユーザー名/リポジトリ名 形式で保存され、ghqコマンドで管理できるので便利。 Fish Shell Fish Shell bash->zshを使ってきたけど、なんかモダンなのを使ってみたくて移行。使い勝手が違いすぎてはじめは苦労するけど、進化しているなぁと実感。Homebrewをインストールしていれば環境構築は楽。 oh-my-fish/oh-my-fish oh-my-fish/oh-my-fish fish shellを便利にするスクリプト集的なもの。fish shellを使うなら入れておいたほうがいい。また、oh-my-fishのテーマを選択できるが、agnosterを使用している。またプラグインの類も設定。 powerline/fonts powerline/fonts oh-my-fishのagnosterはpowerline/fontsが必須なため、設定。 iTerm2をPreferencesで設定。 anyenv/anyenv anyenv/anyenv もはや1つの言語しか使わないにしても複数言語を使うにしても、使ったほうがいい。以上。 ちなみにPyenvでPython3.7以降をインストールするときはこちらを参照。 Dracula Dracula iTerm2のカラーテーマ。ちょっと毒々しいけど見やすい! とりあえずこんな感じになった。

Googleの円周率31兆4000億桁までの計算について、きちんと解説

さて、問題です(デーデン) 円周率とは何でしょう? 割と答えられない人が多いと思う。わかっている人でも「直径を1とするときの円の周囲の長さ」という人も多い。が、厳密には「円の直径と円周の長さの比率」というのが正しい。 とはいえ、円周率が「円の直径と円周の長さの比率」として使われる事のほうがいまとなっては少なくなっている。円周率は数学や物理学、広くは工学や経済学など幅広い分野で出現してくる不思議な数。もはや、「円の直径と円周の長さの比率」以外の意味があるのではないかとすら思えてくる数だ。 歴史的には古く、紀元前より円周率という考え方ではないものの、小学校で習う円の半径と面積の関係であったり、中学校以降で習う球の半径と表面積と体積の関係などが知られていた。昔の人、すごい。 円周率の厳密な値 現代数学では、円周率は厳密な値を求めることに対してあまり興味を持っていない。しかし、過去には様々な人達が円周率の厳密な値を求めることに注力していた。例えば、紀元前の数学者アルキメデスは、次のような方法で円周率を求めようとした。 円を円に内接する正多角形と円に外接する正多角形ではさむことで、円周は内接する多角形の辺の長さの和よりは大きく、外接する円の辺の長さよりは小さいという事実を利用して求めていく。正多角形の辺の数が増えれば増えるほど円に近づくため、徐々に円周に近づいていくというわけだ。この手法によって、円周率は3.14に近い数値であることが明らかとなる。ちなみにこの手法はアルキメデスの時代より2000年のあとに、ドイツの数学者・ガウスによって定式化される「はさみうちの原理」の元となっている。その後も様々な人によって3.14に近かったり遠かったりの円周率の値が導き出されることになる。西洋ばかりでなく中国の学者たちも円周率を計算し、有名なところでは祖冲之が3.1415929まで求めたことが知られている。かなりあとになるが、日本人も村松茂清が3.1415926まで求めている。またそれまでの数学的に言うといわゆる幾何学(図形を扱う分野)ではなく、例えばフランスの数学者・ド・モアブルは解析的に確率論を用いた手法で円周率を求めたりした。 厳密な値を求めることから少しそれて、円周率が無理数であることは知られている。無理数とは、ご存知だろうか。詳しくはSoftware Design3月号あたりを参照いただきたいが、無理数とは「分数で表せない数」である(個人的には実数のうち有理数でない数、と言いたい)。円周率が無理数であることは古代の哲学者(といってしまっていいのか疑問の余地はあるが)アリストテレスによって予想されていた。それを1761年にドイツの数学者・ランベルトによって証明される。つまり円周率は2000年くらい、よくわからない数だったのだ。ちなみに「「10桁で終了」 円周率ついに割り切れる」というニュースを真に受けている人とあったことがある。その後、様々な方法で円周率が無理数であることの証明がされている。無理数である以上、小数点以下の最後の数というのはないのである。 1900年代に入ると、コンピュータの登場で躍進する。天才として名高いフォン・ノイマンによるノイマン型コンピュータの開発により、2037桁まで計算された。その後はアルゴリズムの進歩はありつつも、コンピュータの進化によって今回のような莫大な桁数までの円周率が計算されている。 円周率はどうやって求める? それほど膨大な円周率をどのように求めるか。最初は上で図示したとおり、図形によって計算していたが、徐々に解析的な手法での計算方法が編み出され、アルゴリズム化された。円周率が出てくる代表的な関係式でいうと、ライプニッツの定理(後にライプニッツよりその300年前にインドの数学者・マーダヴァによって考案されたことがわかった)と呼ばれる やゼータ関数(バーゼル問題とも呼ばれる) などが知られているが、こういった式は円周率を求めるのには不向きである。円周率を求めるには、収束速度が鍵となる。収束速度とは簡単に言えば、一気にある値に定まる速度である。次の図を見てみよう。 青いグラフと赤いグラフだと、右に行くに従って赤いグラフのほうがはやく0に近づいていることがわかる。円周率を求める際にも、できる限り早く円周率に近づく数式を使ったほうが効率的である。 いくつか有意義な円周率の求め方を紹介する。まずインドの数学者・ラマヌジャンが発見したラマヌジャン法である。ラマヌジャンは次のような式を考案した。 Oops, ページを閉じないでほしい! このような数式を求められたのはラマヌジャンくらいのもので、神が教えてくれない限り思いつくわけがない数式をラマヌジャンは発見している。しかもラマヌジャン法は精度が高く、また収束速度も早いことが知られている。 モンテカルロサンプリング法という方法もある。これは数式というよりもアルゴリズムで、正方形の中に正円を書きランダムに点を打って、円の中に点が入る確率を求めるというものである。プログラミングをしてもそれほど難しくなく実装できる。 また、つい最近まで使われていたかなり精度も高く収束速度も早いアルゴリズムで、ガウス=ルジャンドルのアルゴリズムがある。詳しくはWikipediaを参照してもらえるとわかるが、ラマヌジャン法よりもとてもシンプルに求めることができる。実際に、2009年までの円周率の最高桁数、約2兆6000億桁はガウス=ルジャンドルのアルゴリズムで求められた。 では今回はどのような方法で求められたのだろう。今回はアメリカの数学者・チュドノフスキー兄弟によって考案されたチュドノフスキーのアルゴリズムが使用された。嫌にならないでほしい。チュドノフスキーのアルゴリズムは次のとおりである。 記事を打っているだけでも嫌になってしまったが、今回の結果はこの数式が使われた。Wikipediaに書いてあったため、一応Pythonでのコードの例も記載する。  プログラムに起こすと少しは簡単に見えるかもしれない。単純にループして計算しているだけだ。単純に……。 円周率を求めるには、アルゴリズムの選定はかなり重要だ。しかし現実的にはむしろ、コンピュータの性能がものをいうのである。Googleは演算に特化したスーパーコンピュータを持っている。これが今回の結果につながったことは街がないと言える。ただし、すごいコンピュータを使えばいいというわけでもない。コンピュータ内でのCPUやメモリの効率化や分散方法など、様々な条件を整えなければならない。数学だけでなく、技術力も試される世界だ。 計算結果って正しいの? 今回、円周率は約31兆桁計算された。つまり、これまで人類が知ることができなかった桁の円周率がわかったということである。しかし、これは本当に正しいのか?正しいと誰が判断したのか?円周率の正しさを証明するために使われるのはまた数学だ。 今回の検証では、2つの数式によって確認された。1つはベラードの公式、もう一つはベイリー=ボルウェイン=プルーフの公式(BBP法) だ。ベラードの公式は、BBP法よりも高速に計算できることが知られている。 ベラードの数式は次のとおりである。もうここまで読んだのだから付き-合ってほしい。 また、BBP法は次のとおりである。 よく打ち込んだと褒めてほしい(褒めなくて良い)。これらの数式は高速で円周率を計算できる。「ではこれを使えばいいのではないか?」と思うだろうが、そうは簡単には行かない。ベラードの公式とBBP法は両方とも、任意の桁数目の円周率を高速に求めることができる数式なのである。そのため、すべての桁数を求めることはできるが、その1桁ずつ求めていく必要があるため時間がかかってしまう。そのため、他のアルゴリズムで計算された数式の確認にのみ用いられるのである。 最後に 数学的にはそれほど新しい技術が使われていないが、Googleの世界最高峰の人材と技術が成し遂げた結果である。漠然と「円周率を求めただけじゃん」と思ってしまうが、上でも言ったとおり、数学的には具体的な円周率を知ること自体にそれほど興味はない。円周率を求めることは、コンピュータの性能を計る手段であり、それが今までの結果を圧倒する計算スピードとなったのである。 もし今後量子コンピュータが完成すれば、おそらく円周率の桁数は兆とか京とかそのレベルではない計算ができるようになるだろう。「2位ではだめなんですか?」とか「三角関数なんて誰が使うんですか?」などと政治家が言っている国では、とても追いつけるものではない。