
Haskell
Haskellの将来性についてその歴史から紐解く
序文:純粋関数型プログラミング言語 Haskell(ハスケル) Haskell(ハスケル)は純粋関数型プログラミング言語です。Haskell(ハスケル)は数学者であり論理学者でもあるハスケル・カリー氏の名前が由来となっているプログラミング言語です。Haskell(ハスケル)を知るにあたって、純粋関数型プログラミング言語とは何かを知ることが重要となってきます。 純粋関数型プログラミング言語は関数型プログラミング言語の一部であり、命令形プログラミング言語と対比されることが多いプログラミング言語です。関数型プログラミング言語は変数の初期化や代入がないことが大きな特徴となっています。 同じ処理を繰り返すことを繰り返し処理と言いますが、これを実行するために通常はループというものを使います。例えば、商品計算のシステムがあったときに、商品によって価格は異なるため、商品の情報をデータベースから取ってきて、それを足し合わせる処理を繰り返しやる必要があります。 その際に、命令形プログラミング言語だとループによって合計額として定義した変数にそれぞれの商品の価格が代入され、最終的な合計額が変数として見える形になります。一方で、関数型プログラミング言語では繰り返し処理をメソッドとして再帰的に呼び出すことで、それぞれの商品の価格を合計し、最終的に合計額を出します。 命令形プログラミング言語で触れた変数の再代入と入出力によってプログラムの状態を副作用と言い、この副作用を持たないプログラミング言語を純粋関数型プログラミング言語と言います。このような副作用があると、テストやデバッグを困難にさせたり、プログラムの動作が複雑で分かりづらいという恐れがあります。 命令形プログラミング言語はコンピューターによって理解しやすいプログラミング言語ですが、純粋関数型プログラミング言語は人間にとって読みやすいプログラミング言語となっています。この純粋関数型プログラミング言語の中でも、副作用のような機能を持つモナドという機能があるのがHaskell(ハスケル)です。 Haskell(ハスケル)の誕生:前身となった言語、Miranda Haskell(ハスケル)の誕生に大きく関わっているのはHaskell(ハスケル)の前身となったプログラミング言語であるMirandaが1985年にリサーチソフトウェア社から発表されました。このMirandaは当時に数多くあった純粋関数型プログラミング言語の中でも、一番多くの人に使われていたプログラミング言語です。 ただ、Mirandaはリサーチソフトウェア社が開発したこともあり、著作権が発生していたので、オープンソースとして皆さんが使えるものではありませんでした。そこで、1987年にFunctional Programming Languages and Computer Architectureという会議によってオープンソースであるプログラミング言語が開発されるべきという意見が多数あり、Haskell(ハスケル)開発のための委員会が発足し、実際に開発に至りました。 一番最初にリリースがされたHaskell(ハスケル)はHaskell1.0という名称でリリースがされました。ここからHaskell(ハスケル)というプログラミング言語が進化をしていきます。 Haskell(ハスケル)の黎明期:非公式に進むプロジェクト 実際に、Haskell1.0が誕生し、その後にHaskell(ハスケル)は黎明期を迎えます。Haskell1.0のバージョンアップのための開発は進み、1997年後半には挙動がより安定し、機能を拡張するためにライブラリーが搭載されたHaskell98がリリースされました。 その後に、Haskell98を更に進化させるHaskell′(Haskell Prime)というプロジェクトが非公式に進みました。 続いて、Haskell2010が2010年に発表されました。これは他のプログラミング言語とのバインディングを可能にするもので、それを可能にする機能であるForeign Function Interface(FFI)が追加されました。 Haskell(ハスケル)の成長期:エンジニアにとって実用的で使いやすい言語に Haskell(ハスケル)はHaskell2010の発表以降に、バージョンアップを繰り返し、更に実用的で使いやすい言語に成長を遂げています。 また、Haskell(ハスケル)を参考に開発がなされたプログラミング言語もあります。その一つがCleanです。Cleanは純粋関数型プログラミング言語で、Haskell(ハスケル)と仕様が非常に似ています。Haskell(ハスケル)は変数の再代入と入出力によってプログラムの状態である副作用をモナドという機能を使うことで扱いますが、Cleanは一意型という一貫性のある表現を使います。 このようにHaskell(ハスケル)だけではなく、Cleanといった純粋関数型プログラミング言語全体で成長を遂げています。 Haskell(ハスケル)の現在:セキュリティ対策のために利用される言語に 現在、Haskell(ハスケル)はその使いやすさや汎用性から多くの企業に支持されており、国内外問わず使用されています。 Haskell(ハスケル)の良さは開発における信頼感とスピード感です。早く開発しなければならないが、複雑なシステムを開発しなければならないといった難易度の高いシステムを開発するときに重宝されるのがこのHaskell(ハスケル)です。ただ、JavaやRubyなどの有名な言語に比べると、使用している企業は少ないです。 海外だと、皆さんご存知のFacebook社がHaskell(ハスケル)を利用しています。マルウェア対策やスパム対策といったセキュリティ対策のために利用されているようです。国内ですと、業務パッケージの開発・販売をしているワークスアプリケーションズ社が使用していたり、金融の高頻度取引で有名なTsuru Capital社が使用をしています。 Haskell(ハスケル)は優秀なプログラミング言語であるものの、他のプログラミング言語に比べて開発に大きな費用がかかる・習得難易度が高いという特徴があります。そのため、小さなベンチャー企業やフリーランスに用いられることはあまり多くはありません。 Haskell(ハスケル)を使用している企業は優秀なエンジニアと潤沢な資金がある企業ばかりです。実際にHaskell(ハスケル)を使えるエンジニアを募集している転職の求人数を調べてみても、他のプログラミング言語とは大きな開きがあります。ただ、導入企業は昔よりも増えているので、今後の将来性には期待できるでしょう。 まとめ:Haskell(ハスケル)は有名企業も採用する言語 プログラム言語の歴史 <Haskell(ハスケル)編> というテーマで今回はお伝えしました。いかがだったでしょうか? 今回お伝えしたかったことは以下のとおりです。 Haskell(ハスケル)は関変数の初期化や代入がないことが大きな特徴である関数型プログラミング言語であるHaskell(ハスケル)はオープンソースである純粋関数型プログラミング言語を開発すべきという意見から開発がなされたHaskell(ハスケル)はHaskell(ハスケル)はその使いやすさや汎用性から多くの企業に支持されており、国内外問わず使用されている 今回はプログラミング言語であるHaskell(ハスケル)を見てきましたが、Haskell(ハスケル)の知名度はそこまで無く、一部の方しかご存知ないプログラミング言語だと思います。現在、求人数が少なく、仕事で使うという観点で他のプログラミング言語と比べるとやや劣るプログラミング言語ですが、成長を遂げて将来性もあると言われています。 そのため、Haskell(ハスケル)を学ぶことはプラスになると言えるでしょう。また、Haskell(ハスケル)は純粋関数型プログラミング言語という珍しい分類に入るプログラミング言語であり、有名企業も採用しているプログラミング言語であるので、趣味程度でも是非触ってみることをオススメします。 フリーランス案件を探す

Ruby on Rails
gemとは何か 【Ruby, Ruby on Rails】
gemとは何か gemとはrubyのライブラリのことを指します。 gemの扱い方 gem list でインストール済みのgemの確認ができる $ gem list *** LOCAL GEMS *** actioncable (5.2.1, 5.2.0, 5.1.6, 5.1.4) actionmailer (5.2.1, 5.2.0, 5.1.6, 5.1.4) actionpack (5.2.1, 5.2.0, 5.1.6, 5.1.4) actionview (5.2.1, 5.2.0, 5.1.6, 5.1.4) activejob (5.2.1, 5.2.0, 5.1.6, 5.1.4) activemodel (5.2.1, 5.2.0, 5.1.6, 5.1.4) activerecord (5.2.1, 5.2.0, 5.1.6, 5.1.4) activestorage (5.2.1, 5.2.0) activesupport (5.2.1, 5.2.0, 5.1.6, 5.1.4) addressable (2.5.2) archive-zip (0.11.0) arel (9.0.0, 8.0.0) ast (2.4.0) bigdecimal (default: 1.3.4) bindex (0.5.0) bootsnap (1.3.1) builder (3.2.3) bundler (1.16.4, 1.16.3) byebug (10.0.2, 9.0.6) capybara (3.4.1) childprocess (0.9.0) chromedriver-helper (1.2.0) 〜省略〜 rails に関連するgemを探したい場合は gem search -r rails で探すことができる $ gem search -r rails *** REMOTE GEMS *** aa-rails4 (0.6.0) aaronchi-jrails (0.5.1) aavkontakte-rails3 (0.1.9) ab-experiments-rails (0.0.3) abcjs-rails (3.0.1) access-granted-rails (0.1.0) access-watch-rails (0.0.3) access_policy_rails (0.0.2) access_watch_rails (0.1.2) accessible-bootstrap3-rails (0.2.4) account_kit_rails (0.0.0) accountingjs-rails (0.0.4) ace-rails (0.0.2) ace-rails-ap (4.2) ace_editor-rails (0.0.1) ace_vimtura-rails (0.1.3) aced_rails (0.2.1) ack_favicon_maker_rails (1.0.2) ack_rails_admin_jcrop (0.2.0.2) ack_rails_admin_settings (1.2.3.3) act-fluent-logger-rails (0.5.0) 〜省略〜 なお、ブラウザで確認したい場合は下記を参照 ruby-toolbox RubyGems.org gem のインストールは gem install rails で可能だが、あまりお勧めできる方法ではない。 bundler で管理するのが常套 bundlerとは bundle inatall などで使われる bundler 。実はこれもgemの一つである。 用途はgemの管理。 gemを複数使っていると、依存関係が出てくる。 バージョンが??だの、あのgemがないだの言われる。 それをbundlerで管理する。そのファイルがGemfileである。 source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.5.3' gem 'mysql2', '>= 0.4.4', '< 0.6.0' gem 'puma', '~> 3.11' gem 'rails', '~> 5.2.2.1' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' # gem 'mini_racer', platforms: :ruby gem 'coffee-rails', '~> 4.2' gem 'jbuilder', '~> 2.5' gem 'turbolinks', '~> 5' # gem 'redis', '~> 4.0' gem 'bootsnap', '>= 1.1.0', require: false gem 'mini_magick', '~> 4.8' gem 'aws-sdk' gem 'carrierwave', '~> 1.0' gem 'config' gem 'devise' gem 'devise-i18n' gem 'draper' gem 'exception_notification' gem 'fog-aws' gem 'font-awesome-rails' gem 'gretel' gem 'kaminari' gem 'ranked-model' gem 'ransack' gem 'slack-notifier' gem 'slim-rails' gem 'yaml_vault' group :development do gem 'listen', '>= 3.0.5', '< 3.2' gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' gem 'web-console', '>= 3.3.0' gem 'better_errors' gem 'bullet' gem 'capistrano' gem 'capistrano-bundler' gem 'capistrano-rails' gem 'capistrano-rbenv' gem 'capistrano-yarn' gem 'capistrano3-puma' gem 'guard-rspec', require: false gem 'rack-mini-profiler' gem 'rails-flog', require: 'flog' gem 'simplecov', require: false end 〜省略〜 source 'https://rubygems.org' でホスティングサーバーを指定。 gem 'rails', '~> 5.2.2.1' でrails のバージョンを指定。 group :development do gem 'listen', '>= 3.0.5', '< 3.2' gem 'spring' gem 'better_errors' gem 'bullet' end 本番環境で使うgemを指定。 こんな感じでgemを記載していく。 Gemfileを書き終えたら、bundle insrall でGemfileに記載された通りにインストールする。 その際に、Gemfile.lockを作成する。 このファイルがgemのバージョンをロックしバージョンが変わらない様にしてくれる。 つまり、gemが更新されても使用するgemのバージョンはそのままにしてくれる。 Gemfile.lockを更新したいときは bundle update を使う。 フリーランス案件を探す

Ruby on Rails
Gem Deviseによるパスワードの保存及び保安方法
はじめに Rails フレームワークを利用するアプリケーションでは登録とログインモジュールにDevise gem と bcryptがよく使っています。DeviseはRailsでおそらく最も人気な認証機能を実装できるgemです。 ユーザーのパスワードの暗号化とログイン確認に対してDeviseはデフォルトでbcryptを使用しています。 bcryptを利用しない例 下記はbcryptを利用しない認証フォローの1つ例です。 1. ユーザーが登録する時、パスワードはハッシュして、データベースに保存します。 2. ログインする時、入力したパスワードをハッシュして、データベースに保存したハッシュしたパスワードと比べて、一致したら、ログインできます。一致しなければ、「バイバイ」ですね。このアプローチには、暗号化アルゴリズムが常にパスワードが渡された固定文字列を返すという大きな欠点があります。例えば、SHA1アルゴリズムで使えば、”password” というストリングはハッシュした後いつも ”5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8”というストリングを返します。 これにより、ハッカーがデータベースを攻撃し、ユーザーのパスワードハッシュであるデータを取得すると、ハッカーは、Rainbow Tableを作成してユーザー全体のパスワードを取得するために、一度だけ総当たりする必要があります(パスワード「password」または「123456」を持つユーザーは同一のハッシュ文字列を持っているため)。 したがって、同じパスワード文字列が他のハッシュを生成するソリューションが必要ですが、ユーザーがログインすると、比較結果が一致する必要があります。 そのため、パスワードに「salt」を追加する必要があります。 Bcryptによる、salt はランダムストリングです。Saltのおかげで、毎回ハッシュする時、違うストリングを返します。 bcryptを利用する例 下記はbcryptを利用する認証フォローの1つ例です。 1. ユーザーが登録する時、ランダム saltを発行して、saltとパスワードをハッシュして、encrypted_passwordを取得して、データベースに保存します。encrypted_passwordはsalt を含みます。パスワード同じですが、saltはランダムから、毎回ハッシュするのは新しいencrypted_passwordを作ります。 2. ログインする時, データベースのencrypted_passwordのsaltを取って、入力したパスワードとsaltをハッシュして、ハッシュしたストリングを取得して、そのストリングとencrypted_passwordを比べて、一致したら、ログインできます。 例えば、”my password”というストリングをbcryptで使って下記の形の1つ例でencrypted_passwordと呼びます。 $2a$12$K0ByB.6YI2/OYrB4fQOYLe6Tv0datUVf6VZ/2Jzwm879BW5K1cHey 今encrypted_passwordを分析します。 2a (最初の$の2つの間): bcrypt暗号化アルゴリズムバージョン12 (次の$の2つの間):costと呼ばれます。costの役割は何か後で分析します。K0ByB.6YI2/OYrB4fQOYLe(最後$の後のキャラクターの22個): saltと呼ばれています。6Tv0datUVf6VZ/2Jzwm879BW5K1cHey(最後キャラクターの31個): ctextと呼ばれます。ctextはsaltとパスワードからハッシュされます。 Costについて Costを説明いたします。 Costとは、ハッシュを何回実行するか、つまりどれだけ遅いかという尺度です。 あなたはそれを遅くしたい。 繰り返しますが、これはハッシュされたパスワードが盗まれた場合のセキュリティの冗長な層です。何でもブルートフォースするのは法外に高価になります。 Cost は4以上と31以下の数字です。Bcryptアルゴリズムでは例えばcostは12なら、繰り返し数は2^12=4096回。 Cost = log_2 (繰り返し数) なので、cost は高ければ、高くほどパスワードのハッシュは安全になります。 しかし、逆にcostが高ければ、高くほどハッシュの速度も遅くなります。 bcryptアルゴリズムです。 bcryptアルゴリズム 詳しくはhttps://ja.wikipedia.org/wiki/Bcryptで参考できます。 それだけパスワード保安方法は安全と思いますか? ランダムsaltはRainbow Tableを作成するコストを増加させましたが、人生は不明ですが、攻撃者は常に自分が望むものを達成する想像を絶する動機を持っています。攻撃者がスーパーコンピューターを持っているとデータベースを攻撃し、データを手に入理とします。そのスーパーコンピュータには、データのencrypted_passwordとsaltから、Rainbow Tableを作って、パスワードを見つけられます。 それでは、このリスクを最小限に抑える方法は?原則は、すべての卵を1つのバスケットに入れるのではなく、pepperです。Pepperはsaltに似たランダム文字列ですが、違いは、pepperを秘密にして、データベース以外の場所に保存する必要があることです。また、ユーザーあたりのpepperは必要ありません。ユーザーの全ては1pepper十分です。 Deviseはpepperを使っているのを見えられます。 Bcryptでhash_sceret(password, salt)からbcryptでhash(password, salt, pepper)に使うのはもっと安全になります。 ハッカーはデータベースを手に入っても、pepperがないから、rainbow tableを作れない、パスワードを取れないです。 ノート:攻撃者が何らかの方法でdbユーザーを持っていると想定している記事では、実際にはこれは非常に困難です。インフラストラクチャの設計など、他のセキュリティレイヤーがあるためです。それらの問題について話しません。 参考 Gem devise https://github.com/plataformatec/devise bcryptアルゴリズム https://ja.wikipedia.org/wiki/Bcrypt Gem bcrypt-ruby https://github.com/codahale/bcrypt-ruby Rainbow table https://ja.wikipedia.org/wiki/レインボーテーブル







