たくみん成長日記

開発とか趣味とかラブライブとかラブライブとかラブライブとか

Sinatraのdatabase.ymlでdotenvを使いたい

こんちか!! たくみんです。最近はSinatraを使って、ちょっとしたWebアプリを作っています。その際にハマったポイントがあるので、備忘録として記事を書いています。

開発中のアプリケーションの構成は、以下のような感じです。

  • rbenv : 1.1.1-39-g59785f6
  • ruby : 2.6.0
  • sinarra : 2.0.5
  • mysql : Ver 8.0.13 for osx10.14 on x86_64 (Homebrew)
./
├── app.rb
├── config.ru
├── database.yml
├── Gemfile
└── Gemfile.lock

ハマったポイント

今回開発中のアプリケーションでは、databaseに接続するための情報を、database.ymlに記述することにしました。

qiita.com

しかしながら、ユーザネームやパスワードなどの情報を、GitHubのpublicリポジトリにpushするのは、あまりよくありません。 そこで、.envgem dotenvによる管理を行うことにしました。

Railsのdatabase.ymlには、erb記法が利用できるという記事を発見したので、Sinatraでも行けるでしょと思い、やってみることにしました。

shuzo-kino.hateblo.jp

そのときのdatabase.ymlとSinarraのapp.rbは以下のような感じです。

adapter: mysql2
encoding: utf8
reconnect: false
database: sqlapps
pool: 5
username: <%= ENV["MYSQL_USERNAME"] %>
password: <%= ENV["MYSQL_PASSWORD"] %>
host: localhost
require 'sinatra'
require 'sinatra/reloader'
require 'mysql2'
require 'dotenv'
require 'yaml'

set :bind, '0.0.0.0'
Dotenv.load
sql_client = Mysql2::Client.new(YAML.load_file('./database.yml'))

get '/' do
  # 省略
end

Sinatraを起動してみると、以下のように、erb記法がうまく解釈されておらず、接続ができていないことがわかります。

Access denied for user '<%= ENV["MYSQL_USERNAME"] %>'@'localhost' (using password: YES) (Mysql2::Error::ConnectionError)

解決方法

解決方法が以下の記事に乗っていました。

www.ohmg.tokyo

この記事によると、以下の手順を踏むことで、解決できるようです。

  1. File.readでdatabase.ymlを読み込む
  2. ERB.new()の引数に、1.を与える
  3. 2.の結果をresult methodで取り出し、yamlとして読み込ませる
  4. 3.の結果をmysql2の引数として与える

コードにすると以下のような感じです。

Mysql2::Client.new(YAML.load(ERB.new(File.read("./database.yml")).result))

修正結果

解決方法を踏まえて、Sinatraのapp.rbを以下のように修正しました。

require 'sinatra/base'
require 'sinatra/reloader'
require 'mysql2'
require 'dotenv'
require 'yaml'
require 'erb'

class SQLApplication < Sinatra::Base

Dotenv.load
yaml_file = File.read("./database.yml")
sql_client = Mysql2::Client.new(YAML.load(ERB.new(yaml_file).result))

  get '/' do
    query = "select * from test1"
    output = ""
    result = sql_client.query(query)
    result.each do |a|
      output =  a["text"]
    end
    return output
  end
end

疎通確認として、適当なテーブルを作成し、表示させてみます。 テーブルは以下のような感じです。

test1
+---------------+-------------+
| id(integer)   | text (text) |
+---------------+-------------+
|    1          | test        |
+---------------+-------------+

表示結果が下の画像です。 f:id:takuminv:20190115020854p:plain

成功です。うまくQueryの結果を表示していることがわかります。

終わりに

Railsだと、コマンド叩いてけばdatabase.ymlが勝手に作られ、 dotenv-railsのおかげで、勝手にerbを解釈してくれるので、楽なのですが、 Sinatraだと全部自分でやらないといけないので、勉強になりました。

やっぱりRailsってすごい…

Unityちゃんを英雄王にしてみた

こんちか!! たくみんです。この記事は、SLP KBIT Advent Calendar 2018の18日目の記事になります。

qiita.com

本題に入りますが、Fateに興味をもちまして、Fate/stay night [Unlimited Blade Works]を視聴しました。

一応最後まで見たんですが、「王の財宝」がかっこよすぎるんですよね。まず、「王の財宝」と書いて、「ゲートオブバビロン」というのが、かっこいいし、迫力も凄いし、もう半端じゃないって思いました。 f:id:takuminv:20181216215245j:plain:w400

そして、思いました。

そうだ、Unityでやろう。

「王の財宝」の確認

まず、「王の財宝」を確認して、どのような要素で構成されているのか、確認してみましょう。 確認すると、「王の財宝」は3つの要素で構成されていることがわかります。

  1. 宝具(剣とか槍とか)
  2. 宝具を射出するやつ
  3. 英雄王本人

f:id:takuminv:20181216220921j:plain:w400

これをUnityで再現します。 つまり、「Unityちゃんが「王の財宝」を使って、的に対して攻撃する」を再現します。 この記事では、「王の財宝」を生成する部分まで紹介します。

Assetの準備

まずは、「王の財宝」を再現するための、Assetを探します。

1. 宝具

宝具に見えるAssetは、下記のものにしました。これなら、無料で使用できますし、それっぽいですからね。 assetstore.unity.com

2. 宝具を射出するやつ

宝具を射出するやつは、下記のものにしました。AssetStoreには、無料でいいものがなかったので、こちらにしました。 ktk-kumamoto.hatenablog.com

3. 英雄王本人

英雄王は、Unityちゃんにしました。ほとんど初めてのUnityなので、下記のQiitaの記事を参考にしました。

qiita.com

assetstore.unity.com

assetstore.unity.com

今回作成したObjectの紹介

今回Scene上に生成するObjectは以下です。

  • Player(Playerが操作するUnityちゃん)
  • target(「王の財宝」の的になるObject)
  • aura_ground(宝具を射出するやつ)
  • sword(宝具)
  • mask_sword(後述)

「王の財宝」を生成するスクリプト

生成するスクリプトは、PlayerにAddしているSwordGeneratorというスクリプトです(くそコードなのは許してください)。とりあえず、Hキーを押すことで、「王の財宝」を生成することにしました。

public class SwordGenerator : MonoBehaviour {

    GameObject sword;
    GameObject mask_sword;
    GameObject sword_circle;
    GameObject player;
    GameObject target;
    // Update is called once per frame

    private void Start()
    {
        sword = (GameObject)Resources.Load("Prefabs/WeaponSword002");
        mask_sword = (GameObject)Resources.Load("Prefabs/Cylinder");
        sword_circle = (GameObject)Resources.Load("Prefabs/aura_ground");
        player = GameObject.Find("Player");
        target = GameObject.Find("target");
    }
    void Update () {
        if (Input.GetKeyDown(KeyCode.H) )
        {
            //---- arua_ground(宝具を射出するやつ)の生成
            Vector3 pos = new Vector3(Random.Range(-20.0f, 20.0f) + player.transform.position.x, player.transform.position.y + Random.Range(2.0f, 12.0f), player.transform.position.z);

            Vector3 pos_circle = pos;

            Vector3 aim = target.transform.position - pos;
            
            Quaternion look = Quaternion.LookRotation(aim);

            pos_circle = pos_circle + (look * new Vector3(0f, 0f, 1.1f));
            Instantiate(sword_circle, pos_circle, look);

             //---- sword(宝具)とmask_swordの生成
            switch(Random.Range(0,11))
            {
                case 0: sword = (GameObject)Resources.Load("Prefabs/WeaponSword000"); break;
                case 1: sword = (GameObject)Resources.Load("Prefabs/WeaponSword001"); break;
                case 2: sword = (GameObject)Resources.Load("Prefabs/WeaponSword002"); break;
                case 3: sword = (GameObject)Resources.Load("Prefabs/WeaponSword003"); break;
                case 4: sword = (GameObject)Resources.Load("Prefabs/WeaponSword004"); break;
                case 5: sword = (GameObject)Resources.Load("Prefabs/WeaponSword005"); break;
                case 6: sword = (GameObject)Resources.Load("Prefabs/WeaponSword006"); break;
                case 7: sword = (GameObject)Resources.Load("Prefabs/WeaponSword007"); break;
                case 8: sword = (GameObject)Resources.Load("Prefabs/WeaponSword008"); break;
                case 9: sword = (GameObject)Resources.Load("Prefabs/WeaponSword009"); break;
                case 10: sword = (GameObject)Resources.Load("Prefabs/WeaponSword010"); break;
            }

            Vector3 axis_x = new Vector3(1f, 0f, 0f);
            Quaternion q_x = Quaternion.AngleAxis(90f, axis_x);

            Vector3 axis_y = new Vector3(0f, 1f, 0f);
            Quaternion q_y = Quaternion.AngleAxis(90f, axis_y);

            look = Quaternion.LookRotation(aim, Vector3.up);
            look = look * q_x * q_y;

            Instantiate(sword, pos, look);
            Instantiate(mask_sword, pos, look);

        }
        
    }
}

ひとつずつ説明していきます。

aura_ground(宝具を射出するやつ)の生成

aura_ground(宝具を射出するやつ)の生成を行います。 このコードで行っている処理は、以下の通りです。

  1. playerの座標と、Random.Range()により、aura_groundを生成する座標を決定
  2. aura_groundの座標とtargetの座標の差と、Quaternion.LookRotation()によりtargetの方向を向くようにする
  3. aura_groundの座標を、targetがいる方向に1.1fずらす(宝具の先っぽの方で、aura_groundを生成するため)。
  4. aura_groundの生成
 //---- sword(宝具)を射出するやつの生成
//-- 1.
Vector3 pos = new Vector3(Random.Range(-20.0f, 20.0f) + player.transform.position.x, player.transform.position.y + Random.Range(2.0f, 12.0f), player.transform.position.z);
Vector3 pos_circle = pos;
//-- 2.
Vector3 aim = target.transform.position - pos_circle;
Quaternion look = Quaternion.LookRotation(aim);
 //-- 3.
pos_circle = pos_circle + (look * new Vector3(0f, 0f, 1.1f));
//-- 4.
Instantiate(sword_circle, pos_circle, look);

1. aura_groundを生成する座標を決定

aura_groundを生成する座標を決定します。Unityちゃんの周りに生成してほしいため、Unityちゃんの座標とRandom.Range()を使用します。これにより、Unityちゃんの座標が中心として、一定の範囲内にarua_groundが生成されるようになります。また、今回はZ座標は、Unityちゃんの座標のままにしているので、aura_groundは、XY平面上に生成されます。 イメージとしては、下図のような感じです。赤丸がUnityちゃんだとすると、赤四角の範囲内に、aura_groundが生成されます。

f:id:takuminv:20181217003216p:plain:w500

2. targetの方向を向くようにする

targetの方向を向かせるために、以下のサイトを参考にしました。

code.hildsoft.com

3. targetの方向に座標をずらす

Vector3型のベクトルにQuaternionを掛け合わせることで、ベクトルを回転させることができます。これにより、「現在の座標」に「target方向に向いた大きさ1.1fのベクトル」を足すことで、座標をずらしています。

4. aura_groundの生成

Instantiate()で生成しているだけです。

sword(宝具)の生成

sword(宝具)の生成を行います。 このコードで行っている処理は、以下の通りです。

  1. 生成するsword(宝具)をランダムで決める
  2. aura_groundと、Object自体の向いている方向?が異なっているため、補正
  3. sword(宝具)とmask_swordの生成
//---- sword(宝具)とmask_swordの生成
//-- 1. 
switch(Random.Range(0,11))
 {
    case 0: sword = (GameObject)Resources.Load("Prefabs/WeaponSword000"); break;
    case 1: sword = (GameObject)Resources.Load("Prefabs/WeaponSword001"); break;
    case 2: sword = (GameObject)Resources.Load("Prefabs/WeaponSword002"); break;
    case 3: sword = (GameObject)Resources.Load("Prefabs/WeaponSword003"); break;
    case 4: sword = (GameObject)Resources.Load("Prefabs/WeaponSword004"); break;
    case 5: sword = (GameObject)Resources.Load("Prefabs/WeaponSword005"); break;
    case 6: sword = (GameObject)Resources.Load("Prefabs/WeaponSword006"); break;
    case 7: sword = (GameObject)Resources.Load("Prefabs/WeaponSword007"); break;
    case 8: sword = (GameObject)Resources.Load("Prefabs/WeaponSword008"); break;
    case 9: sword = (GameObject)Resources.Load("Prefabs/WeaponSword009"); break;
    case 10: sword = (GameObject)Resources.Load("Prefabs/WeaponSword010"); break;
 }
//-- 2.
Vector3 axis_x = new Vector3(1f, 0f, 0f);
 Quaternion q_x = Quaternion.AngleAxis(90f, axis_x);

Vector3 axis_y = new Vector3(0f, 1f, 0f);
Quaternion q_y = Quaternion.AngleAxis(90f, axis_y);

 look = Quaternion.LookRotation(aim);
 look = look * q_x * q_y;

//-- 3.
Instantiate(sword, pos, look);
Instantiate(mask_sword, pos, look);

1. ランダムでsword(宝具)を生成

Random.Range()とswitch文により、生成するPrefabを変えています。でもこの書き方はちょっとダサい気がするので、何かいい方法を知っていれば教えてください。

2. 向きの補正

「王の財宝」を再現するためには、sword(宝具)とaura_groundが同じ方向を向いている必要があります。では、以下の2つの画像を見てください。この2つの画像では、2つとも同じ上方向を向かせているつもりなのですが、ObjectのRotationを確認すると、まったく違う方向を向いていることがわかります。そのため、ただ、targetの方向を見るだけでは不十分であり、向きの補正が必要なのです。

f:id:takuminv:20181217005629p:plain:w300f:id:takuminv:20181217005635p:plain:w300

4. 宝具の生成

sword(宝具)をInstantiate()するわけですが、このままでは、aura_groundの裏側にもsword(宝具)が表示されてしまいます。「王の財宝」を再現する場合、以下の画像のように、aura_groundの裏側になる部分は、隠れていないとダメなのです。

f:id:takuminv:20181217195247p:plain:w400

では、どのようにして、指定の部分のみを非表示にするのか。その答えが以下の記事にありました。 つまり、別のオブジェクトを重ねることで、見かけ上隠すということです。

nn-hokuson.hatenablog.com

今回は、swordより少し大きいCylinderをswordに重ねることで、隠すことに成功しました。

f:id:takuminv:20181217225523p:plain:w400

スクリプトの実行結果

実行してみると、かなりそれっぽくなっていることがわかりますね。個人的には大満足です。 f:id:takuminv:20181217014143p:plain:w500

感想

ほとんど初めてのUnityだったので、Prefabってなに?Assetってなに?からのスタートでした。一番わからないのは、Quaternionですね。定義やリファレンスを見てもワケワカメ状態でした(そもそもベクトルがわからん)。3Dゲームを作るとなると、数学の知識が必要になってくるらしいので勉強しないとまずいかなって感じです。

おわりに

とりあえず「王の財宝」の生成までの記事を書いてみました。次は、射出する話であったり、背景と地形(Unlimited Blade Works再現)の話などを書いていこうかなと思います。ではでは。

ラブライブ!サンシャイン!! Aqours 4th LoveLive! ~Sailing to the Sunshine~に現地参加してきました!!

こんちか!!たくみんです。2018年11月17日、18日に東京ドームで行われたラブライブ!サンシャイン!! Aqours 4th LoveLive! ~Sailing to the Sunshine~の1日目に現地参加してきました!! f:id:takuminv:20181121004502p:plain:w500

いままで、1st、2nd、3rdと現地参加してきましたが、いままでで一番素晴らしく感動したライブになりました!この記事では、ライブの内容と感想について書いていこうかなと思います。

ライブ概要

  • 日時 : 11月17日 17:00~20:30、18日 16:00~19:30
  • 場所 : 東京ドーム
  • 動員数 : 15万人(ライブビューイング含め)

日時は、最初に書いた通り、11月17日、18日で、場所は東京ドームです。動員数は、ライブビューイング含め15万人とかなり大規模なライブとなりました。いままで行ってきたライブの中でもトップの動員数です。チケットの選考抽選申込券は、1日目、2日目それぞれ「ラブライブ!サンシャイン!!」TVアニメ2期Blu-ray第7巻特装限定版(1)とAqours 4th LIVE テーマソングCD「Thank you, FRIENDS!!」(2)に封入されています。また、4thライブでの初の試みとして、加藤達也氏率いる浦の星交響楽団によるオーケストラ演奏がありました。加藤達也氏は、ラブライブサンシャインの楽曲を担当している人で、今回のライブでは、アニメに使用されたBGMを生オーケストラで聞くことができました。

(1)f:id:takuminv:20181120225522j:plain:w300 (2)f:id:takuminv:20181120225524j:plain:w200

1日目の流れ

1日目は、以下のように進行しました。アンコール含め以下の22曲が披露されました。

ーMCー(コーレス)

ーアニメ振り返り映像(with フルオーケストラ)ー

ーMCー

ーアニメ振り返り映像(with フルオーケストラ)ー

  • 12.MY舞☆TONIGHT
  • 13.待ってて愛のうた
  • 14.未熟DREAMER

ーアニメ振り返り映像(with フルオーケストラ)ー

  • 15.MIRAI TICKET
  • 16.キセキヒカル(with オーケストラ)

ーMCー(浦の星交響楽団撤収+Saint snow登場)

  • 17.Awaken the power

ーMCー(Saint snow挨拶)

ーMCー(劇場版最新情報・最後の挨拶)

  • アンコール3.Thank you, FRIENDS!!

これから、それぞれの感想を話していきたいと思います。

OP. Main theme of Lovelive! Sunshine!(フルオーケストラ)

ラブライブのライブは、開始時間になると同時に、メンバー紹介のムービーが入ります。今までは、ムービーのBGMはCD音源??であり、生の演奏ではありませんでした。 ライブが始まる前から、オーケストラの楽器が見えていたのでまさかとは思っていましたが、生演奏が聞けるとは思いませんでした。 やはり、生オーケストラだと、迫力が違いましたね(笑)今までのライブにはなかったものをいきなりぶっこんで来たので、「今回のライブは今までと違う!」感がすごかったです!

1. 君のこころは輝いてるかい?

「君のこころは輝いてるかい?」は、記念すべきAqoursの1stシングルに封入されているAqoursのデビュー曲です。1曲目はアニメ1期のOPである「青空Jumping Heart」かアニメ2期のOPである「未来の僕らは知ってるよ」のどちらかだと思っていたため、いきなり予想を外されました。1曲目が「君ここ」だったため、1stライブのことを思い出してすごく感動したとともに、テンションが上がって叫びまくっていました(笑)

f:id:takuminv:20181121032908j:plain:w200

2.Step!ZERO to ONE

「Step!ZERO to ONE」は、「君のこころは輝いてるかい?」と同じCDに収録されており、1stライブの代表曲にもなっています。Aqoursの目標の一つである「0を1にする」に対する思いが込められており、「君ここ」と同様にAqoursはここから始まったといえる曲です。「君ここ」と「Step!ZERO to ONE」が最初に来たのは、Aqoursの原点を思い出させるためなのかもしれません。

3. 恋になりたいAQUARIUM

恋になりたいAQUARIUM」は、「君ここ」の次に発売した2ndシングルの曲です。この曲のセンターは、事前に行われた第1回人気投票で1位となった渡辺曜が担当しました。「恋になりたいAQUARIUM」にはPVがついているのですが、そのPVでの曜ちゃんが可愛すぎて、全国の渡辺曜推しは、天に召されたことでしょう(私は、津島善子推しなのでセーフでした)。いつものライブでは、中盤に歌われることが多い印象だったのですが、3曲目でぶっこんできましたね。私の周りにいた人たちも、「恋アクくるのはやくないか!?」や「今回のセトリやばいかも」と言っていました。

f:id:takuminv:20181121032918j:plain:w200

MC(コーレス)

ライブ恒例のコール&レスポンスです。メンバーごとにコール&レスポンスが決まっていて、Aqoursラブライバーでやり取りが行われます。楽曲ごとのコールは覚えられなくても、最悪このコーレスを覚えていればなんとかなります。なので、ライブに参加する人は、メンバーとのコーレスは覚えておいた方がいいかもしれません。 今回のコーレスで最高によかったのは、黒澤ダイヤ役の小宮有紗さんとのコーレスですね。小宮さんはいつも、ファンに対して、「好きよ」と言うのですが今回はアドリブで「しゅき」に変えてきたんですね。もうこれはやばかったです。もうやばかったです。まあこのあと肝心のコーレスをするのを忘れてしまったのが小宮さんっぽくておもしろかったです(笑)

4. 少女以上の恋がしたい

この曲は、Aqoursの3rdシングル「HAPPY PARTY TRAIN」に収録されているカップリング曲の一つです。いままでのAqpursの曲とは違い、かなり恋愛を意識した曲で、全体的にかわいいかんじの曲となっています。ですが、この曲が来るとはまったく思っていませんでした。今回のライブは、「アニメの曲」+「シングルの曲」が中心になると思っていたので、来るとしても「HAPPY PARTY TRAIN」だと思っていました(「HAPPY PARTY TRAIN」は2日目に披露されたようです)。曲が可愛いのもそうなのですが、振り付けもかなりかわいいので、ぜひライブ映像を見ることをおすすめします。

5. 青空Jumping Heart

この曲は、アニメ1期のOPであり、アニメ2期13話のラブライブ本選のアンコールでも歌われた曲です。1期のOPだったので、この曲でAqoursを知った人も多いんじゃないでしょうか。私自身も、アニメ1期が始まったころはそこまでハマっていなくて、せっかくアニメが始まったんだから見ようかなくらいだったのですが、今では生活の7割がAqoursに染まってしまいました。この曲は必ず来るとはおもっていたのですが、「少女以上の恋がしたい」の次に来るとはおもっていなかったので、「ここで来るのか!」って感じでしたね。コールがかなりお盛り上がる曲の1つなので、全力で大声を出していました。

f:id:takuminv:20181121033325j:plain:w200

アニメ振り返り映像(with フルオーケストラ)

Aqpursのメンバーが次の衣装に着替えてる間に、アニメ1期のダイジェスト映像が流れました。しかもフルオーケストラ付きです。1期のダイジェストだったので、「次は1期の曲か!?何が来るんだ!?」って感じでした。

6. 決めたよ Hand in Hand

この曲は、アニメ1期1話のエンディング(挿入歌)です。Aqoursの2年生3人の曲で、テンポが速く、かなり明るい曲になります。個人的に好きな曲の一つなので、この曲が来てくれたことがとてもうれしかったです。

f:id:takuminv:20181121033533j:plain:w200

7. Waku-Waku-Week!

この曲は、アニメ1期ブルーレイの3巻に収録されている1年生3人の曲です。1年生3人の仲の良さが伝わってくるような楽しい曲になっています。この曲は、2ndライブのブルーレイでは見たことがあったのですが、生で見たのは初めてだったので、とてもうれしかったです。

8.G線上のシンデレラ

この曲は、アニメ1期ブルーレイの5巻に収録されている3年生3人の曲です。1年生の曲とは打って変わって、大人っぽいワルツをテーマにした曲です。ライブでは、3年生3人と1年生3人がペアとなって、ワルツを踊っていました。個人的に好きな楽曲ランキングベスト5に入る曲なので、「Waku-Waku-Week!」同様、生で聞けて良かったです。

9. 想いよひとつになれ(9人バージョン)

もうこの曲を聴くだけで泣きそうになってしまいます。この曲は、アニメ11話の挿入歌であり、ラブライブの予備予選で、Aqoursが披露した曲です。桜内梨子が出場するピアノコンクールとラブライブの地区予選の日にちがかぶってしまい、梨子がピアノコンクールへの出場を辞退しようとしていたところに、主人公である高海千歌が「ピアノコンクールに出てほしい」と、背中をおし、梨子はピアノコンクール、他8人は、ラブライブ地区予選に出場します。そして、梨子はコンクール入賞、Aqoursは地区予選突破を果たすアニメ屈指の感動話です。また、梨子がコンクールで発表した曲に歌詞をのせたのがこの「思いよひとつになれ」となっています。1stライブでは 桜内梨子役の逢田梨香子さん(通称りきゃこ)がピアノ未経験にもかかわらず、「思いよひとつになれ」のピアノ演奏を行うなど、Aqoursの曲のなかでも1位、2位を争う曲なのではないでしょうか。今回の4thライブでも、りきゃこがピアノとともに登場したので、ピアノ演奏かと思ったのですが、今回は違いました。なんと、8人の曲だった「思いよひとつになれ」を桜内梨子含めた9人の曲として、披露したのです。フォーメーションや、歌う順番もすべて9人用に作り直しており、この時点で私は泣いていました。振り付けの途中で、りきゃこが高海千歌役の伊波杏樹さんの手を奪う部分があったのですが、そこも感動しました。

f:id:takuminv:20181121033552j:plain:w200

MC

このMCでは、6. 7. 8. 9.の楽曲についてのMCでした。このMCでりきゃこが「思いよひとつになれをみんなと一緒に踊るのがゆめだった。Aqoursのメンバーがフォーメーションなどを一緒に考えてくれた。」と言ったときに、Aqoursのメンバーの絆がとても強いこと、メンバーがラブライブにかけている気持ちが伝わってきて、号泣してしまいました。1stライブのときも泣きそうになってましたが、今回は、泣いちゃいましたね。

10. 聖なる日の祈り

この曲は、「ジングルベルがとまらない」に収録されているカップリング曲です。クリスマスをテーマとするバラードとなっています。Aqoursからの早めのクリスマスプレゼントということで披露されました。いままでの1st、2nd、3rdは5月から9月に行われることが多かったため、ライブで披露されることはなかったのですが、今回初のお披露目となりました(ミニライブなら披露されています)。歌っているときにメンバーがランタン??のようなものをもっていて、かなり幻想的な雰囲気となっていました。また、最初に「聖なる日の祈り」がきたため、「ジングルベルがとまらない」は2日目に来るのかなと思っていました。

11. ジングルベルがとまらない

と思ったら、「聖なる日の祈り」の次に来ましたね。こちらは「聖なる日の祈り」とは違い、かなりアップテンポで明るい曲となっています。「ジングルベルに乾杯!!」と「ジングルベルとまんない!!」はかなり印象にのこるフレーズで、コールも大盛り上がりでした。

f:id:takuminv:20181121033633j:plain:w200

アニメ振り返り映像(with フルオーケストラ)

ここは確か、アニメ1期後半とアニメ2期前半だったかな??ちがってたらごめんなさい。水分を補給するとともに、アニメの振り返りができるので、よかったです。

12.MY舞☆TONIGHT

この曲は、アニメ2期の3話の挿入歌で、ラブライブの予備予選で披露した曲になります。アニメ2期の2話で、1年生と3年生の6人が力を合わせて作成した曲でもあります。和風な感じの曲で、衣装は花魁を若干イメージしていると思われます。3rdライブでも披露されていたのですが、MY舞☆TONIGHTの衣装が披露されたのは今回が初だったので、迫力が強まっていました。

f:id:takuminv:20181121012949j:plain:w200

13. 待ってて愛のうた

この曲は、Aqours2ndシングル「恋になりたいAQUARIUM」に収録されているカップリング曲です。この曲はCメロがかなり好きで、メンバーひとりひとりがソロで歌うのですが、ライブでも全員が縦一列に並び、ひとりひとり歌いながら移動していくというかなり好きな振り付けになっています。しかし、今回のライブでは、メンバーがステージ横いっぱいに並び、歌いながら中央に戻るといういままでと違ったものだったのでとても驚きました。

14. 未熟DREAMER

この曲は、アニメ1期の9話挿入歌です。Aqoursが9人になって初めて披露した曲でもあります。この未熟DREAMERの衣装は浴衣なので、それに近いMY舞☆TONIGHTの衣装もとてもマッチしていました。今回のライブは、楽曲の順番が本当に読めなくて、次に何がくるのか全然わかりませんでした。

f:id:takuminv:20181121033652j:plain:w200

アニメ振り返り映像(with フルオーケストラ)

おそらくアニメ2期後半だったかな。

15. MIRAI TICKET

この曲は、アニメ1期の13話挿入歌であり、ラブライブの東海地区予選で披露した曲です。今回のライブでは、Aqoursシップと呼ばれる大船に乗って登場し、Aqoursシップ上で踊りました。このときほどアリーナ席がうらやましかったことはありません。

16.キセキヒカル(with オーケストラ)

この曲は、アニメ2期のブルーレイ7巻に収録されている曲です。また、「キセキヒカル」はアニメのBGMに歌が載せられたものとなっており、今回のライブでは、オーケストラ演奏とともに披露されました。ライブでの披露は今回が初でした。この曲のほかアニメ2期ブルーレイ全館購入特典の3曲は卒業や別れがテーマなので、Aqoursの終わりを考えてしまい、すこし悲しくなってしまいます。

MC(浦の星交響楽団撤収+Saint snow登場)

「キセキヒカル」を披露したことで、浦の星交響楽団は会場全員の拍手とともに撤収していきました。オーケストラの迫力はすさまじいもので、ここまで変わるのかと思いました。また、スペシャルゲストとして、AqoursのライバルユニットであるSaint Snowが登場しました。

17. Awaken the power

この曲は、アニメ2期9話の挿入歌であり、Aqoursの9人とSaint Snowの2人を合わせたグループ「Saint Aqpurs Snow」の曲であり、妹である黒澤ルビィと鹿角理亜が、姉である黒澤ダイヤと鹿角聖良に送る曲です。「Awaken the power」はラブライブサンシャインの楽曲の中で一番盛り上がる曲だと思います。サビでの「Hi! Hi! Hi!」のコールは、会場全体が一体となることができるコールです。3rdライブでも披露されましたが、その時も超大盛り上がりでした。

f:id:takuminv:20181121033726j:plain:w200

MC(Saint snow挨拶)

このMCでは、Saint Snowの2人がMCの中心となっており、東京ドームの景色を見せてくれたラブライブAqoursのメンバーに感謝の気持ちを伝えていました。

18. No.10

この曲は、4thライブテーマソング「Thank you, FRIENDS!!」に収録されているカップリング曲であり、ファンのみんなはAqoursの10人目だということを伝えてくれる曲です。この「ファンのみんなはグループの10人目」というのは、μ'sのときから続いているものでラブライブを代表する要素の一つなんじゃないかと思っています。また、Aqoursのメンバーも一緒に歌おうといってくれて、会場の6万人(ライブビューイング含め7.5万人)で合掌しました。

19. ユメ語るよりユメ歌おう

この曲は、アニメ1期のED曲です。ラブライブのED曲は、会場全員で歌うことが恒例となっているため、「No.10」と同様に、全員で歌いました。また、コールも存在しているため、歌いながらコールをするのはなかなか大変でした(笑)2日目には、「ユメ語るよりユメ歌おう」ではなく、アニメ2期のED曲である「勇気はどこに?君の胸に!」が披露されたようです。ここでいったんライブが終了し、Aqoursコール(アンコール)が行われました。 通常のアンコールでは、「アンコール!アンコール!」と叫ぶと思うのですが、Aqoursでは、「Aqours!Aqours!」と叫びます。これは、3rdライブから始まったもので、おそらくアニメ2期11話で、Aqoursコールが行われたことが原点となっていると思います。

アンコール1. 未来の僕らは知ってるよ

この曲はアニメ2期のOPです。コールがかなり盛り上がったのですが、なにより衣装がすさまじかったです。アンコール明けから、「Thank you, FRIENDS!!」の衣装に着替えており、可愛すぎて死ぬかと思いました。 個人的にも好きな曲なので、「ここで、来るかぁ」と思いました。

f:id:takuminv:20181121033934j:plain:w200

アンコール2. WONDERFUL STORIES

この曲は、アニメ2期13話の挿入歌であり、3rdライブのテーマとなった曲です。アニメ2期のOPのあとに、アニメ2期の最後の曲を持ってきたのがとてもいいと感じました。Aqours高海千歌がずっと探してきた「輝き」はいままで歩んできた道、みんなで過ごしてきた時間だったのだと結論付けるこの曲は、Aqoursの集大成ともいえる曲の1つではないでしょうか。いまでも13話のこの曲を聴くたびに鳥肌が立ってしまいます。ライブでも鳥肌バチバチでした。

f:id:takuminv:20181121033951j:plain:w200

MC(劇場版最新情報・最後の挨拶)

まず最初に年明けの1月4日に公開される劇場版の新情報が公開されました。最後のあいさつでは、メンバーがどれだけラブライブというコンテンツが好きなのか、Aqoursが好きなのか、ファンのみんなが好きなのかがとても伝わってきて、これからもずっと応援したいと思いました。ラブライブがみんなの夢の手助けになればうれしいとも言っていて、大学生活や、来年から始まる社会人生活を頑張っていこうと思いました。

Thank you, FRIENDS!!

この曲は、4thライブのテーマソングになっている曲です。この曲に関しては、素晴らしい曲以外の感想が思いつかないくらい素晴らしい曲だと思います。この曲を聴いていると、高校生の時μ'sにであってよかった。大学2年生のときにAqoursに出会ってよかったと、とても思います。ラブライブに出会っていなかったらこんな楽しい経験はできなかったと思いますし、ここまで何かに打ち込むこともなかったと思います。 ライブの3時間半が本当にあっという間で、Thank you, FRIENDS!!を歌い終わって、メンバーが退場した後、ちょっとした虚無感がありました。

f:id:takuminv:20181120225524j:plain:w200

全体の感想

今回のライブは、いままでやってなかったことに多く挑戦しているライブだと感じました。生オーケストラであったり、思いよひとつになれ9人バージョンであったり、Aqoursシップの登場などですね。また、セトリもAqoursの始まりから現在に至るまでを網羅するようなものになっており、Aqoursがたどってきた道を再確認できる素晴らしいライブでした。中でも一番はやはり、「思いよひとつになれ」ですね。私は、映画等を見てもなくタイプではないのですが、今回は本当に号泣してしまいました。このおかげで、AqoursのFinalライブでは絶対に泣くことが確定しましたね(笑)。それだけ私のなかでラブライブというコンテンツは大きなものになっていると再認識しました。本当に最高のライブでした!!ありがとうございました!!1日目には発表されなかったのですが、5thライブの開催が発表されたので、必ず現地参加したいと考えています。

おまけ

ライブ終了後に、会場限定の「Thank you, FRIENDS!! SOLOCONCERT」を購入し、御茶ノ水にある神田明神に行きました。

Thank you, FRIENDS!! SOLOCONCERT

会場限定で発売された「Thank you, FRIENDS!!」の全員のソロ曲が収録されているものです。最高すぎて、通学中は常に車の中で聴いています。正直売り切れると思っていたのであきらめていたのですが、購入することができてとてもよかったです。

f:id:takuminv:20181121031932j:plain:h400

神田明神

ライブ終了後に、神田明神に行ってきました。東京ドームの最寄り駅である水道橋駅神田明神の最寄り駅である御茶ノ水は隣同士なので、歩いていきました。同じことを考えている人が大量にいて、40人ぐらいの人と一緒になって移動しました。実は、6月の3rdライブの時にも神田明神を訪れており、その時の絵馬に「4thライブに当選すること」、「第一志望の企業から内定をもらうこと」の2つを書きました。そのおかげが、両方とも叶えることができたので、そのお礼もかねて(というかそれが目的)参拝しました。本当は、ライブが始まる前に行き、絵馬を書く予定だったのですが、時間の見通しがあまく、ライブ終了後となってしまったため、絵馬は書けませんでした。

RaspberryPi +Sinatra + SlackBotでエアコンを遠隔操作しよう(全体説明編)

こんちか!!たくみんです。最近、とても寒くなってきましたね。私も家にいる間は暖房をつけています。 こうなると問題になるのが、エアコンの消し忘れです。私はとても忘れっぽい性格なので、よくエアコンを消し忘れてしまっています。 というわけで、自分の部屋のエアコンを外から操作できるシステムを開発しました。この記事含め、4つの記事で紹介していきたいと思います。

エアコン遠隔操作の考え方

エアコンやテレビなどの家電製品は、リモコンで操作することが多いです。そしてそのリモコンは、「電源オン」、「電源オフ」等の操作に対応した赤外線を家電製品に送信して動作させています。 つまり、リモコンが送信する赤外線と同じパターンの赤外線を送信することができれば、家電製品を操作できることになります。 今回は、Raspberry Piを用いて、リモコンが送信している赤外線を解析し、まったく同じパターンの赤外線を送信することで、遠隔操作を実現します。また、外部から操作する方法として、SlackBotを採用しました。SlackBotのほかに、デスクトップアプリも開発したのですが、ポート開放をしないといけないことやCSRF(クロスサイトリクエストフォージェリ)の対策を考えないといけないので、今回はSlackBotを採用しています。

使い方

使い方は簡単です。以下のようにSlack上の桜内梨子ちゃんBotに、「冷房」、「暖房」、「電源オフ」と伝えることでそれぞれ、「冷房をつける」、「暖房をつける」、「電源を消す」という動作をさせることができます。現在はまだ開発途中なので、温度を変えることはできません。梨子ちゃんの口調に違和感があるのでこれから直していきます。

f:id:takuminv:20181115000841p:plain:w500

システム構成

このシステムは、Raspberry PiとSlackBot(Ruby製)とSinatraで構成されています。 SinatraはRasberryPi上に構成されており、SlackBotから、SinatraサーバにGETリクエストすることで、赤外線を送信するスクリプトを実行し、エアコンを操作します。操作した後は、json形式でエアコンの状態をSlackBotに返却し、Slack上で通知します。現在は、DB等を使用していないのですが、もしかすると、エアコンの状態や遠隔操作した時間などをDBに保存するかもしれません。

f:id:takuminv:20181115011006p:plain:w500

おわりに

このシステムにより、エアコンを消し忘れたとしても、外から消すことが可能になりました。また、家に帰る直前にエアコンをつけておくことで、家に着いた頃に室温を最適にしておくこともできるようになりました。残る3つの記事は、「Raspberry Pi編」、「Sinatra編」、「SlackBot編」となります。ではでは。

picoCTF2018 WriteUp 100点以下編

こんちか! たくみんです。2018.09.28(金)から2018.10.12(金)まで行われたpicoCTFに挑戦してみました。競技に参加したのが10.08(月)から、10.09(火)だったので、実質5日間で競技に取り組みました。 最終結果が以下のようになります。この内、General Skillsの400点問題1問と、Web Exploitationの300点問題1問、400点問題1問は大会終了後に解いているので実際は6735点が最終結果となります。

f:id:takuminv:20181015013704p:plain:w500

ぼくもCTFのWriteUpをやってみたかったので、記事にしてみます。picoCTFは問題の数が多かったので、複数回にわけて行いたいと思います。 今回は、100点以下の問題全14問のWriteUpを行います。

Forensics Warmup 1 - Points: 50

問題文

Can you unzip this file for me and retreive the flag?

ヒント

Make sure to submit the flag as picoCTF{XXXXX}

解答

ファイルがDLできるようになっているので、DLしてみます。するとflag.zipというファイルがDLできるので、素直にunzipコマンドを実行してみましょう。

$ unzip flag.zip

すると、flag.jpgという画像ファイルが出現します。開いてみるとフラグ獲得!

flag

f:id:takuminv:20181015014625j:plain:w500

Forensics Warmup 2 - Points: 50

問題文

Hmm for some reason I can't open this PNG? Any ideas?

ヒント

How do operating systems know what kind of file it is? (It's not just the ending! Make sure to submit the flag as picoCTF{XXXXX}

解答

pngファイルが何故か開けないようです。Warmupなので、そこまで難しくはないはず。というわけでとりあえずfileコマンドを実行してみましょう。

$ file flag.png
flag.png: JPEG image data, JFIF standard 1.01, resolution (DPI), density 75x75, segment length 16, baseline, precision 8, 909x190, frames 3

いや、めっちゃJPEGやん!!PNGちゃうやん!!
というわけで、flag.pngをflag.jpgになおしてフラグ獲得!!

flag

f:id:takuminv:20181015015546j:plain:w500

General Warmup 1 - Points: 50

問題文

If I told you your grade was 0x41 in hexadecimal, what would it be in ASCII?

ヒント

Submit your answer in our competition's flag format. For example, if you answer was 'hello', you would submit 'picoCTF{hello}' as the flag.

解答

ASCIIコード上で、0x41は何だろう?という問題です。こんな時は、ASCll表の出番ですね。

f:id:takuminv:20181015020004p:plain:w500

はい、ASCll表をみると0x41Aになっていますね。なので、picoCTF{A}がフラグになります。

flag

picoCTF{A}

General Warmup 2 - Points: 50

問題文

Can you convert the number 27 (base 10) to binary (base 2)?

ヒント

Submit your answer in our competition's flag format. For example, if you answer was '11111', you would submit 'picoCTF{11111}' as the flag.

解答

10進数の27は2進数だとどうなりますか?という問題です。27は10進数に直すと61ですね。なので、picoCTF{61}がフラグになります。

flag

picoCTF{61}

General Warmup 3 - Points: 50

問題文

What is 0x3D (base 16) in decimal (base 10).

ヒント

Submit your answer in our competition's flag format. For example, if you answer was '22', you would submit 'picoCTF{22}' as the flag.

解答

16進数の3Dは10進数だとどうなりますか?という問題です。16進数の3Dは10進数に直すと61ですね。なので、picoCTF{61}がフラグになります。

flag

picoCTF{61}

Resources - Points: 50

問題文

We put together a bunch of resources to help you out on our website! If you go over there, you might even find a flag! https://picoctf.com/resources (link)

ヒント

なし

解答

リンク先のページからフラグを見つけろという問題です。おそらくHTMLのなかにあるのではないかと推測しました。 HTML内で、picoCTFと検索するとフラグ発見!!

f:id:takuminv:20181015021003p:plain:w500

flag

picoCTF{xiexie_ni_lai_zheli}

Reversing Warmup 1 - Points: 50

問題文

Throughout your journey you will have to run many programs. Can you navigate to /problems/reversing-warmup-1_1_b416a2d0694c871d8728d8268d84ac5c on the shell server and run this program to retreive the flag?

ヒント

If you are searching online, it might be worth finding how to exeucte a program in command line.

解答

ファイルをDLすると、runというファイルがDLできます。拡張子が書かれていないのでなんのファイルかわかりません。こういう時は、fileコマンドですね。fileコマンドを実行してみましょう。

$ file run
run: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3f4cbb89ad8989bad12dfa913e40072f3d21c96d, not stripped

実行結果から、ELFファイルだとわかりました。 実行ファイルから文字列を見つけるときは、とりあえずstringsコマンドを叩いてみましょう。

$ strings run | grep pico
picoCTF{welc0m3_t0_r3VeRs1nG}

ビンゴ!!!

flag

picoCTF{welc0m3_t0_r3VeRs1nG}

Reversing Warmup 2 - Points: 50

問題文

Can you decode the following string dGg0dF93NHNfczFtcEwz from base64 format to ASCII?

ヒント

Submit your answer in our competition's flag format. For example, if you answer was 'hello', you would submit 'picoCTF{hello}' as the flag.

解答

base64のdGg0dF93NHNfczFtcEwzという文字列をデコードしろという問題ですね。ググってみると、ブラウザ上でデコードしてくれるサイトがあるようなので、ぶち込みます。

www.convertstring.com すると、dGg0dF93NHNfczFtcEwz → th4t_w4s_s1mpL3
となるので、picoCTF{th4t_w4s_s1mpL3}がフラグですね。

flag

picoCTF{th4t_w4s_s1mpL3}

Crypto Warmup 1 - Points: 75

問題文

Crpyto can often be done by hand, here's a message you got from a friend, llkjmlmpadkkc with the key of thisisalilkey. Can you use this table to solve it?.

ヒント

Submit your answer in our competition's flag format. For example, if you answer was 'hello', you would submit 'picoCTF{HELLO}' as the flag. Please use all caps for the message.

解答

table.txtというファイルがDLできます。中身は以下のとおりです。

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
   +----------------------------------------------------
A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
F | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
G | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
H | H I J K L M N O P Q R S T U V W X Y Z A B C D E F G
I | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
J | J K L M N O P Q R S T U V W X Y Z A B C D E F G H I
K | K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
L | L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
M | M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
N | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
O | O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
P | P Q R S T U V W X Y Z A B C D E F G H I J K L M N O
Q | Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
R | R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
S | S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
T | T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
U | U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
V | V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
W | W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
X | X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y

はい、これはシーザー暗号の上位互換である、ヴィジュネル暗号ですね。鍵の文字によって、ずらす回数が変化するやつです。 Rubyでヴィジュネル暗号を復号するスクリプトを作成しました。(ネットに復号するサイトがあることに後で気づきました…)

strs = "llkjmlmpadkkc"
keys = "thisisalilkey"


strs.each_char.with_index do |str,index| 

  str_ord = str.ord - "a".ord
  key_ord = keys[index].ord - "a".ord
  
  print((((((str_ord + 26) - key_ord) % 26) + "a".ord).chr).upcase)
  
  
end

実行した結果がこちらになります。

$ ruby answer.rb 
SECRETMESSAGE

SECRETMESSAGEなんて完全にフラグっぽいですね。よってフラグはpicoCTF{SECRETMESSAGE}になります。

これは余談ですが、渡された文を平文と鍵の2つだと勘違いしていて、50分位まちがったスクリプトを作り続けていました…

flag

picoCTF{SECRETMESSAGE}

Crypto Warmup 2 - Points: 75

問題文

Cryptography doesn't have to be complicated, have you ever heard of something called rot13? cvpbPGS{guvf_vf_pelcgb!}

ヒント

This can be solved online if you don't want to do it by hand!

解答

で、でた~ROT13奴~。はい、シーザー暗号ですね。ROT13は13文字ずつずらせということです。以下のサイトに暗号をぶち込みました。

ango.satoru.net するとcvpbPGS{guvf_vf_pelcgb!} → picoCTF{this_is_crypto!}になりました。 シーザー暗号の前に、ヴィジュネル暗号が来るのは何故なんでしょう。

flag

picoCTF{this_is_crypto!}

grep 1 - Points: 75

問題文

Can you find the flag in file? This would be really obnoxious to look through by hand, see if you can find a faster way. You can also find the file in /problems/grep-1_2_ee2b29d2f2b29c65db957609a3543418 on the shell server.

ヒント

grep tutorial

解答

問題名からして、grepを使ってみよー的な問題だと思われます。 ファイルをDLします。また拡張子がないのでfileコマンド実行

$ file file
file: ASCII text, with very long lines

ASCllということはstringsコマンドでフラグが見つかるかもしれません。やってみます。

$ strings file | grep pico
picoCTF{grep_and_you_will_find_42783683}

フラグ獲得!!
ちなみにcatコマンドでも獲得できます。

flag

picoCTF{grep_and_you_will_find_42783683}

net cat - Points: 75

問題文

Using netcat (nc) will be a necessity throughout your adventure. Can you connect to 2018shell3.picoctf.com at port 36356 to get the flag?

ヒント

nc tutorial

解答

これも問題名からして、ncを使ってみよー的な問題だと思われます。 2018shell3.picoctf.comの36356番ポートに接続しろとのこと。

$ nc 2018shell3.picoctf.com 36356
That wasn't so hard was it?
picoCTF{NEtcat_iS_a_NEcESSiTy_9454f3e0}

フラグ獲得!!

flag

picoCTF{NEtcat_iS_a_NEcESSiTy_9454f3e0}

HEEEEEEERE'S Johnny! - Points: 100

問題文

Okay, so we found some important looking files on a linux computer. Maybe they can be used to get a password to the process. Connect with nc 2018shell3.picoctf.com 35225. Files can be found here: passwd shadow.

ヒント

If at first you don't succeed, try, try again. And again. And again. If you're not careful these kind of problems can really "rockyou".

解答

passwdとshadowの2つのファイルをDLできます。 psswdとshadowの内容は以下の通りです。

passwd

root:x:0:0:root:/root:/bin/bash
shadow

root:$6$L0grUkkk$H8JS0BBMMpGj8qqVpdvkOoBumhqhP5l2RYyOb/0aNhhgjtoEN4pJW3LVXIl93qieXao/G14AsjstVjJYxBmaz0:17770:0:99999:7:::

passwdを見ると、rootユーザが存在しており、パスワードは、shadowの方にハッシュ化して保存されているようですね。 ググってみると、ハッシュ化されたパスワードを推測するツールにJohn the Ripperがあるようです。 John the Ripperを用いて、ハッシュ化されたパスワードを推測します。

https://www.openwall.com/john/

$ john --show shadow    
root:superman:17770:0:99999:7:::

1 password hash cracked, 0 left

これにより、rootユーザのパスワードはsupermanだと判明しました。この情報を用いて、フラグを獲得しましょう。

$ nc 2018shell3.picoctf.com 35225
Username: root
Password: superman
picoCTF{J0hn_1$_R1pp3d_99c35524}

フラグもjohnとなっているので、John the Ripperを使うことが想定されているようです。

flag

picoCTF{J0hn_1$_R1pp3d_99c35524}

strings - Points: 100

問題文

Can you find the flag in this file without actually running it? You can also find the file in /problems/strings_4_40d221755b4a0b134c2a7a2e825ef95f on the shell server.

ヒント

stringsコマンドのドキュメントページヘのリンク

解答

これもstringsコマンド使ってみよー問題です。今までの問題ですでに使ってしまっていますが、やってみましょう。 stringsというファイルがDLできます。またまた拡張子がないので、とりあえずfileコマンド実行。

$ file strings 
strings: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e5ca61b750713b9161da547bc8ba99efc6e976be, not stripped

はい、ELFファイルですね。stringsコマンドを使う問題なので、stringsコマンドを実行してみます。grepでpicoで絞り込むとおそらくフラグにヒットすると思います。

$ strings strings| grep pico
picoCTF{sTrIngS_sAVeS_Time_d3ffa29c}

やったね。

flag

picoCTF{sTrIngS_sAVeS_Time_d3ffa29c}

おわりに

picoCTFはかなり初心者向けだと感じました。100点以下の問題であれば、linux触りたての人でも解けるのではないでしょうか。 次は、問題数的に、101~199点の問題のWriteUpになると思います。 ではでは。

悪魔の数字判定ツールが完成したってこと。

皆さんこんにちは。関タクミゼイアンです。 もうね、来ちゃったよね。もうやりすぎのカメラがここまで来ちゃってるんだよね。 皆さんはこの記事を覚えているでしょうか?私は入力した数字を悪魔の数字かどうかを判定するツールを作っちゃったんだよね。

takuminv.hatenablog.jp

とうとうこのツールが完成したんだよね。完全にパンドラの箱開けちゃってるよね。以下のリンクで利用できるんだよね。

数字の真実

今回の記事では、変更点や追加した点を取り上げていくんだよね。

1. トップページの追加

前回の記事では、悪魔の数字判定ページしかなかったんだけど、それじゃ味気ないよね。 だから、トップページを作っちゃったんだよね。赤文字の部分が悪魔の数字判定ページへのリンクになってるんだよね。

f:id:takuminv:20181003005012p:plain:w500

ちなみに、赤文字にマウスが乗ると次のように炎が表示されるギミックがあるんだよね。 この炎はgif画像だから、すこしホラーチックなんだよね。

f:id:takuminv:20181003005350p:plain:w500

このギミックは、mouseoverイベントとmouseoutイベントを利用しているんだよね。 以下がそのコードなんだよね。赤文字のリンクには、link-akumaというidを振っていて、炎にはfireというクラス名を割り振っているんだよね。 link-akuma(赤文字のリンク)にマウスが乗ったときに、fireクラスのdisplayをinline(表示)にして、マウスが離れたときに、displayをnone(非表示)にしているんだよね。簡単なんだよね。

$("#link-akuma").mouseover(function() {
    $(".fire").css("display","inline");
}).mouseout(function() {
    $(".fire").css("display","none");
});

2. フォントの変更

悪魔の数字を扱っているのに、普通のフォントじゃ味気ないんだよね。 だから、ホラーチックなフォントに変更したんだよね。 変更前と変更後を比べてみるね。 フォントを変えるだけでここまで印象が変わっちゃうんだよね。

f:id:takuminv:20181003011401p:plain:w500

f:id:takuminv:20181003011404p:plain:w500

使用したフォントは怨霊フォントなんだよね。 暗黒工房 日本語フリーホラーフォント怨霊

ひらがな、カタカナ、数字、漢字に対応していて理想的なフォントだったんだよね。 CSSに以下のようなコードを追加することで、font-familyで怨霊フォントをしようできるようになるんだよね。

@font-face {
    font-family: "Onryou";           /* フォント名 */
    src: url("../font/Onryou.ttf");  /* フォントファイルへのパス */
}

3.色の変更

もっとホラーチックにするために、背景色やグラフの色を変更したんだよね。 背景は白から黒に変更したんだよね。この方がホラーチックだってこと。 グラフの色も黄色と紫に変更したんだよね。選択基準は特にないんだよね。直感ってこと。

f:id:takuminv:20181003011819p:plain:w500

4. GitHub Pagesの利用

GitHubには、GitHub Pagesという機能があるんだよね。 これは、GitHubが提供している、Webページを公開することができる機能なんだよね。 使い方は以下のサイトを参考にしたんだよね。

https://www.tam-tam.co.jp/tipsnote/html_css/post11245.html

それで、公開してみたんだよね。すると、ページの表示にめちゃくちゃ時間がかかっているんだよね。 だから、Chromeの開発者用ツールを利用して、原因を調べてみたんだよね。それが次の画像になるんだよね。 これを見ると、フォントファイルの読み込みに11秒もかかっているんだよね。原因は13Mとかいう容量の大きさだよね。

f:id:takuminv:20181003013352p:plain:w500

4-1. フォントファイルの圧縮

フォントファイルの読み込みを速くするために、ファイルの圧縮を行うんだよね。 これには、サブセット化という手法を用いるんだよね。 フォントファイルの容量が大きい理由は、膨大な文字に対応しているからなんだよね。 つまり、ページで使用しない無駄な文字にも対応しちゃってるってこと。サブセット化というのは、無駄な文字を省くことでファイルを圧縮する手法なんだよね。 サブセット化には、サブセットフォントメーカーというフリーソフトを使用したんだよね。 ダウンロードと使い方は以下のサイトを参照したらいいんだよね。

サブセットフォントメーカー

フォントファイルをサブセット化したファイルに変更して、もう一度GitHubPagesで公開してみたんだよね。すると次のようになったんだよね。 読み込み時間は、0.6秒、ファイルサイズは54kまで減少したんだよね。圧縮のおかげでスムーズに表示されるようになったんだよね。

f:id:takuminv:20181003013323p:plain:w500

4-2. gif画像の圧縮

よく見ると、gif画像も874kBとちょっと容量が大きいんだよね。こいつも圧縮しちゃうんだよね。圧縮には以下のサイトを使ったんだよね。 これは、ブラウザ上でgif画像を無料で圧縮できるんだよね。画像の見た目もほとんど変わらないから便利なんだよね。

www.iloveimg.com

gif画像を圧縮して、もう一度公開した結果が以下の通りなんだよね。圧縮した結果、読み込み時間が1.2秒から0.9秒に短縮できているんだよね。 容量も、531kBと40%くらい圧縮できているんだよね。 これで、皆さんも安心、快適に悪魔の数字ツールを使うことができるんだよね。人類の選別はもう始まってるんだよね。

f:id:takuminv:20181003015105p:plain:w500

5. おわりに

もう完全にやりすぎのカメラがここまで来ちゃってるんだよね。 数字に、こんなことが隠されてるの。それにじゃあ何故皆さんは気づかなかったのって話。 もしかしたら、世界はもうやばいところまできてるかもしれない。 信じるか信じないかはあなた次第です。

github.com

悪魔の数字はごく普通の数字に潜んでるってこと

皆さんこんばんは。関タクミゼイアンです。

悪魔の数字は普通の数字に潜んでるんだよね。みんなはそれを理解しているのかって話。

僕はそれを確かめるためのツールを作っちゃったんだよね。
もうパンドラの箱は開いちゃってるんだよね。

ツールの概要

このツールは、数字を入力することで、その数字が悪魔の数字に変換できるかどうかをを知ることができるんだよね。 悪魔の数字に変換する処理は、以下の二つなんだよね。

  1. 1桁ずつ数値を分解し、すべて加算する。

  2. 1桁ずつ数値を分解し、すべて乗算する。

この2つの処理を繰り返して、悪魔の数字にするってこと。
図にすると、以下のような感じだよね。こんな感じで、悪魔の数字にできる処理を探索していくんだよね。

f:id:takuminv:20180919020158p:plain:w500

ツールの見た目

このツールは、ブラウザ上で動かすことができるんだよね。見た目は、以下の画像の通りなんだよね。 textboxに数字を入力し、変換ボタンを押すか、Enterキーを押すことで、変換が始まるんだよね。 f:id:takuminv:20180919003107p:plain:w500

試しに、123を入力してみるね。結果は、以下の画像の通りなんだよね。123というごく普通の数字も悪魔の数字の6になり得るってこと。

f:id:takuminv:20180919003700p:plain:w500

次は、12345676543を入力してみるね。こんな複雑な数字も悪魔の数字になり得るんだよね。

f:id:takuminv:20180919004125p:plain:w500

こんな感じで、このツールを使えばいつも使っている数字が悪魔の数字になり得るかどうかわかるってこと。

ソースコード

じゃあ次は、ソースコードを見ていくね。このツールは、JavaScriptで作ったんだよね。ライブラリとしてjQueryを使ったんだよね。 CSSはかけないから、Bootstrapを使ったんだよね。htmlは大したことないから、省略するね。

main的な

以下のコードは、main的なやつだよね。変換ボタンをクリックすることでクリックイベントが発火するんだよね。 textboxがフォーカスされているときに、Enterキーを押すことでも、イベントが発火するようにしているよ。

ボタンが押されると、まずは、textboxの値を取得して、数値かどうかを確認するんだよね。 数値じゃなければ、警告を表示するってこと。数値であれば、悪魔の数字への変換が始まるんだよね。

//====================================================================
// window.load
//====================================================================
$(function() {

    //----------------------------------------------------------------
    // textboxでEnterキーを押すことで、クリックイベント発火
    //----------------------------------------------------------------
    $('#number').on('keydown', function(e) {

        if (e.which == 13) {
        $('#button').trigger('click');
    }
    });

    //----------------------------------------------------------------
    // 変換ボタンを押すことで、悪魔の数字変換開始
    //----------------------------------------------------------------
    $("#button").click( function () {

        result_text = [];
        akuma_view_init();  // 結果表示要素を初期化
        number = $("#number").val(); // textboxの値を取得
        if(isNaN(number)){ // 値が数値がどうか
            not_number(); // 数値でないなら警告を表示
            return ;
        }
        if (number < 0) { // 数値が負数かどうか
            var chart_data = akuma_number_frequency(number*-1); // 0からnumberまでの悪魔の数字の頻度を求める
            chart_view(chart_data[0], chart_data[1], chart_data[2]); // 円グラフとして表示
        } else { 
            var viewcode = akuma_number(number, result_text); // 悪魔の数字に変換
            view_check_img(viewcode, result_text); // 結果を表示
        } 
    });
});

悪魔の数字に変換するakuma_number()

次は、悪魔の数字に変換するfunctionのakuma_numberを見ていくね。まず初めに、悪魔の数字かどうかチェックするんだよね。 これにより、入力された数値が悪魔の数字ならすぐに結果を表示できるってこと。 悪魔の数字じゃなければ、変換処理が始まるんだよね。 すべて加算する処理1を最初に行って、それでも変換できなければ処理2を行うってこと。

//--------------------------------------------------------------------
// 入力された数字をなんとか悪魔の数字にする
//--------------------------------------------------------------------
function akuma_number(number, result_text) {
    
    var check = check_akumanumber(number, result_text);  // 悪魔の数字かどうかチェック

    if ( check != 0 ) {return check;}
    var result = add_1(number, result_text,0);  // 処理1 すべて加算
    if ( result != 0 ) {return result;}  
    var result = mult_1(number, result_text,0); // 処理2 すべて乗算 
    if ( result != 0 ) {return result;} 
    return 0;
}

処理1のadd_1()と処理2のmult_1()

じゃあ、処理1のadd_1と処理2のmult_1を個別にみていくね。 このadd_1とmult_1は相互再帰を行ってるんだよね。 計算して、悪魔の数字なら終了、それ以外なら、再帰を使ってさらに探索するんだよね。 add_1とmult_1の違いは、計算が加算か、乗算かだけなんだよね。 すごい冗長のにおいがするけど気にしちゃだめなんだよね。

//--------------------------------------------------------------------
// 数字を1桁ずつ分解し、すべて足す (mult_1と相互再帰)
//--------------------------------------------------------------------
function add_1(number, result_text,c) {

    var num = [];
    if (parseInt(number/10) == 0 && (number != 6 || number != 9)) {return 0;} // 1桁になって悪魔の数字じゃなければ失敗

    num = numarray_split(number);  // 数値を1桁ずつ分解
    sum = num.reduce((s, n) => s + n, 0); // すべて加算
    result_text[c] = array_value_text(num, sum,"+"); // 計算過程の文字列を作成
    
    var check = check_akumanumber(sum, result_text);  // 悪魔の数字かどうかチェック
    if ( check != 0 ) {return check;}  // 悪魔の数字なら終了

    var result = add_1(sum, result_text,c+1);  // さらに、処理1を実行(再帰)
    if ( result != 0 ) {return result;} else {result_text.splice(c, 1);}
    
    var result = mult_1(sum, result_text,c+1); // 処理2を実行(相互再帰)
    if ( result != 0 ) {return result;} else {result_text.splice(c, 1);}

    return 0;
}
//--------------------------------------------------------------------
// 数字を1桁ずつ分解し、すべてかける (add_1と相互再帰)
//--------------------------------------------------------------------
function mult_1(number, result_text,c) {

    var num = [];
    if (parseInt(number/10) == 0 && (number != 6 || number != 9)) {return 0;}  // 1桁になって悪魔の数字じゃなければ失敗

    num = numarray_split(number); // 数値を1桁ずつ分解
    sum = num.reduce((s, n) => s * n, 1); // すべて乗算
    result_text[c] = array_value_text(num, sum,"×"); // 計算過程の文字列を作成
    
    var check = check_akumanumber(sum, result_text); // 悪魔の数字かどうかチェック
    if ( check != 0 ) {return check;} // 悪魔の数字なら終了
    
    var result = add_1(sum, result_text,c+1); // 処理1を実行(相互再帰)
    if ( result != 0 ) {return result;} else {result_text.splice(c, 1);}
    
    var result = mult_1(sum, result_text,c+1); // 処理2を実行(再帰)
    if ( result != 0 ) {return result;} else {result_text.splice(c, 1);}

    return 0;
}

悪魔の数字かどうかチェックするcheck_akumanumber()

最後に、悪魔の数字かどうかチェックするfunctionを見ていくね。 悪魔の数字かどうか判定する前に、18を666、27を999に変換、9を6、999を666に変換しているよ。 18は6+6+6、27は9+9+9だから悪魔の数字と同じ扱いなんだよね。9や999は反転させることで、6や666になるから、これも悪魔の数字になり得るってこと。 悪魔の数字6、666、それ以外の3パターンで、返却値を変えているんだよね。この返却値によってどの画像を表示するのか決定するってこと。

//--------------------------------------------------------------------
// 悪魔の数字になっているかチェック
//--------------------------------------------------------------------
function check_akumanumber(number, result_text) {

    number = check_extra_akumanumber(number, result_text);  // 18を666、27を999に変換
    number = check_reverse_akumanumber(number,result_text); // 9を6、999を666に変換

    if (number == 6) { // 悪魔の数字かどうか
        return 1;
    } else if (number == 666) {
        return 2;
    } else {
        return 0;
    }
}

それ以外のfunction

これ以外の、functionはほとんど結果を表示するためのものなんだよね。 htmlに要素を追加しているだけだから省略するってこと。

隠された機能

実は、このツールには隠された機能があるんだよね。 textboxに負数を入れることでその機能を使えるんだよね。 その機能とは、0から任意の数値(入力した負数の絶対値)の範囲でどれだけの数値が悪魔の数字になれるかを円グラフで表示する機能なんだよね。
試しに、-10000と入力してみるね。この場合だと、0から10000の範囲で、円グラフを表示するんだよね、小さいからちょっと見にくいけど、半分以上の数値が悪魔の数字になってるんだよね。 もうこれ完全に来ちゃってるよね。これはもうすごいことだよね。ヤバタクスゼイアンだよね。パンドラの箱は開いちゃったってこと。

f:id:takuminv:20180919013903p:plain:w500

おわりに

数字に隠された真実、私は点を置いただけ。それをつなげるのは皆さんですからね。信じるか信じないかはあなた次第です。