ログイン機能がないサイトで投稿の作者が自分であることを表明する方法の考察

はじめに

もしかすると、僕はかなり見当違いなことを言っているのかも知れない。

もしそうなら教えていただけるとありがたい。Twitterはこちら@ryo33music

ここから

先日、またしょうもない新しいサイトのアイデアが浮かんできて「面倒臭いけど今度作るか〜」となっていた。

何が面倒くさいって、ログイン処理を作るのが面倒臭い。 勝手にOAuthとかをやってくれるライブラリを利用してGoogleとかのアカウントでログインできるようにしても、それでも面倒臭い。 なんでこんな面倒くさいことを、サイトを作るたびにやらないといけないのか。

今日の午前中のことだ。ふと、僕はなんでこのサイトにログイン機能をつけないといけないかということを考えてしまった。

考えてみると、僕がこのサイトにログイン機能をつけたい理由は 「コンテンツの作成者が自分が投稿したということを表明できる手段を用意したいから」 のただ1つしかなかった。(著作権とかは考えていない)

なんで、このたった1つの理由のためだけに、わざわざこんな面倒くさいことをしないといけないのか。

そして、今日の午前中は、これをログイン機能の実装以外で行うにはどんな方法があるのかを考えることに費やされた。 もちろん、授業はかなりしっかり聞いている。

すぐに、投稿を行うサイトの他に、ログインを行って使用するサイトを使用すればいいと気づいた。 ログイン機能のないサイト(以下サイト1)で投稿を行った後、ログインを行っている別サイト(以下サイト2)を用いて表明するという方法だ。

その表明方法を以下の条件と前提の上で考えた。

  • 手軽であること
  • 好きなタイミングで表明できる
  • 誰でも表明が正当か確かめることができる
  • 自分のコンテンツを勝手に他人が作ったことにされない
  • 他人のコンテンツを勝手に自分が作ったことにされない
  • どちらのサイトもテキストデータが投稿でき、それは他の人に書き換えられることがない
  • どちらのサイトもテキストデータ以外が投稿できるとは限らない
  • どちらのサイトも投稿前にURIが分かるとは限らない
  • 先に投稿したほうが表明として有効とみなされる

なんの難しいこともなく、ただハッシュアルゴリズム等を利用すればいい。

具体的な方法はこうだ。

方法1

  1. 他人から分からないような文字列を決める
  2. (1)で決めた文字列をハッシュ関数にかけ、それをサイト1での投稿内にそれとわかるように明記する
  3. 表明したくなったら、サイト2で(1)で決めた文字列と(2)で投稿したコンテンツのURIの二つを用いて表明する

非常にシンプルな方法だ。

ただ、「先に投稿したほうが表明として有効とみなされる」という前提が気持ち悪い。現代の技術では先に投稿したことを完全に証明することは不可能だ。 これを解消するためには「好きなタイミングで表明できる」か「どちらのサイトも投稿前にURIが分かるとは限らない」のどちらかの前提を捨てる必要がある。

投稿日中に追記: 「証明することは不可能」は言い過ぎだった。先に投稿した方が著作権侵害として消される動画サイトとか、パクツイばかりのツイッターとか、なんかそういうことを言いたかった。

「好きなタイミングで表明できる」という条件が無い場合は、このようにすればいい。

方法2

  1. 他人から分からないような文字列を決める
  2. (1)で決めた文字列をハッシュ関数にかけ、それを用いてサイト2で表明する(この時点ではコンテンツは投稿されていない)
  3. サイト1で(1)で決めた文字列と(2)で投稿した表明のURIの二つを明記する

そして「どちらのサイトも投稿前にURIが分かるとは限らない」が無い場合はこうだ。

方法3(サイト2はURIが投稿する前にわかる)

  1. 他人から分からないような文字列を決める
  2. (1)で決めた文字列とサイト2で投稿する時のURIハッシュ関数にかけ、それをサイト1での投稿内にそれとわかるように明記する
  3. 表明したくなったら、サイト2で(1)で決めた文字列と(2)で投稿したコンテンツのURIの二つを用いて表明する

方法2では投稿する順番を逆にして、コンテンツに表明のURIを含めることで、方法3ではハッシュの中身にURIを含めることでそれぞれ解決している。

方法3で表明のURIをサイト1で明記するのではなく、ハッシュする文字列に含めているのは「好きなタイミングで表明できる」という条件があるためだ。 それに、サイト2のURIが先願的に決まる可能性もある。

自動化

もっと言うと確認が自動でできると良い。 コンテンツと表明のURIを渡すだけで表明が有効であるか確かめてくれるサイトがあれば最高だ。

そのためには、やり方を規格化するしか無い。もちろん方法1〜3の全てをサポートしたもので、付加情報もつけられると良い。

友人が競技プロコン用のサーバーフレームワークを作る話

www.adventar.org

これの14日目です。


僕と友人で、競技プログラミングサーバーを作ることになっているので、その話をしようと思います。

経緯

僕たちが所属している部活で、何回か部内での競プロの大会的なものを開催しています。 しかし、現在使用しているサーバーには、対応言語を追加することが難しいこと、手元のマシン以外で動かすことが難しいこと、そもそも自動採点をしていないなどの問題がありました。

そのサーバーは、継続的に利用されることが想定されていなかった状況でその場限りのものとして作られたため、しょうがのないことでした。

そこで僕と友人(@NotFounds8080)で話し合って、簡単に扱える競プロサーバーを作ることになりました。 名前はなんとなくEagleになりました。 それが、一年以上前のことです。

特に開発が進むことなく、こんなにも時間が経ってしまいました。

Eagleが目指すところ

  • コンパイル、実行、採点が自動で行われる
  • 簡単にPaaSなどに置ける
  • 対応言語の追加が容易
  • 問題の定義が容易
  • プログラムの実行場所が可変(設定すればサンドボックス環境などでの実行もできる)
  • ライブラリとして利用できる(ログイン機能をつけただけの上位互換システムとかが簡単に作れる)

このような感じで作るつもりです。

進捗

現在の進捗は以下のような感じです。

この通り、開発は全く進んでいません。

これから

開発にはある程度の時間を要すると思います。

あまり時間があるわけではありませんが、これが完成して似たような活動を行っている部活動やサークルなどで使用してもらえたら嬉しいので、できるだけ頑張るつもりです。

最後に

タイトルが「友人が」となってますが、これは僕があまり競技プログラミングをやらないため、最後まで僕のモチベーションが保つか分からなかったからです。 本当に僕のこうゆうところ良くないと思ってます。本当に申し訳ないです。どうか許してください。

最後まで、読んでいただきありがとうございました。

残りカス

※ この下は最初に勢いで書いていた時、うっかり生成してしまった文章を自分用に残しているだけです。

今から1年くらい前のこと、僕たちシステム研究部は、パソコン室で部内競技プログラミングコンテストを行っていた。

競技が順調に進んでいく中、不満そうな顔をした部員が二人いた。

一人は僕である。僕は、その時使われていたコンテストサーバーではCとC++のプログラムしか使うことができないことに腹を立てていた。*1

そして、もう一人こそが、その時使われていたコンテストサーバーを作った男、池田(@NotFounds8080)だ。 彼は、自分が前に作ったシステムが継続して利用するつもりで作ったわけではなかったために、サポートする言語の追加などに手間がかかることを不満に思っていた。

不穏な空気が流れる中、僕の一言でその空気が一変した。「汎用的な競技プログラミングコンテストサーバーフレームワークを作らないか」と池田に持ちかけたのだ。

それからすぐに作り始めることが決まった。そして、それは後にEagleプロジェクトと呼ばれることになる。*2

*1:腹を立てていたのは嘘

*2:このセリフを書きたかっただけでした

退屈が創造を生む ~ まずはパンツを脱いでSNSを止めよう ~


Playing with a... comb - Mattias Eklundh Guitar Lesson

この動画を見た。 異常なギタープレイもさることながら、クリエイティブな思考に対する彼の考えが興味深かったので共有することにした。


彼によると、クリエイティブな発想のためには退屈が重要だという。

常にオンライン上にいてTwitterFacebookを見てメッセージを送るようなことをしていると、 退屈になるための時間も新しいアイデアを考えるための時間も何もかもを失ってしまう。

退屈であれば、頭を動かして退屈から抜け出す方法を見つける必要がある。そこで何かが生まれる。


実際に、この動画で紹介されている奏法(櫛奏法とでも呼ぶのだろうか?)は、 インターネットもパンツもない状況で、ギターを手にしているときに思いついたとのことだ。

僕は、ギターを弾くのが趣味で曲を作ったりもするのでこれに共感したわけだが、 これは他のいろいろな分野にも言えるのではないだろうか。


例えば、僕の趣味にはプログラムを書くこともあるが、それに対しても似たようなことが言えるだろう。

プログラムというのは、たいてい何かしらの目的や作りたい物があるわけだから、「何を作るか」というのを考えないといけない。 また、実装するときにも「どのように書けば良いコードになるか」ということを考える必要がある。 これらが"クリエイティブ"に相当するのかは、正直どうとも言えないないが、少なくとも、自分で考えて"アイデア"の形にするわけだ。

それらが思いつかないときに僕は、Twitterを見たり、ニコニコ動画のランキングを眺めたりしがちだが、それではいつまで経っても思いつかない。 最終的には、マウスから手を離してキーボードと向き合い、よく考える必要がある。


あとは、技術的な退屈も重要な気がしていて、「つまんねーから自分で作るか」みたいな気概がある人のほうが、面白いものを作れるのかもしれない。*1


兎にも角にも、良いアイデアを得るためには、考える時間を長くするしかない。

しかし、何をするにしても同じように時間は流れるし、人生はとても短い*2。時間は有限だ。

まずはパンツを脱いで*3SNSを止めよう*4

*1:Twitter等ですごい方々を見ていると、そんな気がしてくる

*2:こんな感じの表現何処かで聞いたような気がするけど、なんだったかな

*3:違う

*4:違う

ElixirでDesel-langのパーサを書いた

qiita.com これの11日目です。

はじめに

今回作ったのはDesel言語を扱うためのコマンドラインツールです。(以下desel-cli
github.com

動作例

$ echo "%A a b c\n" | desel - %A
a
b
c
$ echo "%A -a b c\n" | desel - %A
desel: failed to parse the input

0: %A -a b c
      ^ unexpected token
suggestion: element or expression

本記事では、その実装方法などを解説します。
Desel言語自体についてはこの記事では特に触れないので、そちらに興味のある方はryo33/desel-langを参照していただけると幸いです。

コマンドラインツール部分

Elixirでコマンドラインツールを作るのは結構簡単です。
mix.exs内に

  def project do
    [...
     escript: [main_module: YourCLIModule],
     ...]
  end

として、YourCLIModule内でmain/1を定義するだけです。
desel-cliYourCLIModuleに該当するのはlib/desel/cli.exです。
ファイルや標準入力から読み込んだあと、パーサなどの他モジュールにそれを渡してその結果を出力しています。
ここのコードは、重要な処理は特にしていないうえに、かなり雑に書かれてあるのであんまり見る価値はないです。

字句解析と構文解析

desel-cliではパーサコンビネータryo33/Parselix) を用いて字句解析と構文解析を同時に行っています。
コードはlib/desel/parser.exです。
ParselixParselix.Basicからimportしてきた関数、謎の命名規則などが大量に存在しているので何が何だかわからない事になっていますが、 BNFと対比させてみると何をやっているかはわかりやすくなると思います。
BNFgrammer.ebnfにありますが、 ここも雑なので合っているか保証できないです。
ほとんどがBNFから持ってきただけですが、パース結果を扱いやすい形に変換するmap/2や パースに失敗したときのメッセージを'unexpected token'みたいな感じに置き換えるexpect/2などが色々頑張ってます。

パース結果の処理

この処理がこのコマンドラインツールのメインの処理です。
コードはlib/desel/data.exにあります。
ここでやっている処理は主に2つで、パース結果の変換(from_ast/1)と式の評価(elements_by/2)です。
式の評価では、集合に限って(今のところ*1)キャッシュを保存する用にしたり、 いい感じの再帰にしたりして結構頑張っています。*2

Parselixについて

Parselixは僕が「Elixir面白そうだし入門がてら何か作るか」となったときに、 ちょうどパーサコンビネータに興味を持っていたため作ったものです。
今になって読んでみると結構ひどい見た目で、 Elixir初心者だったからと言い訳できないようなところもあったので、この機会に色々書き換えました。
parserマクロで定義できる関数のarityが任意になったのが一番でかくて、パイプで処理を書くときに

[left, parser, right]
|> sequence
|> (&(pick({&1, &2}))).(1)

と、非常に読みにくいコードになっていたところが*3

[left, parser, right]
|> sequence
|> pick(1)

とできるようになりました。

これから

CLIモジュールのテストは面倒くさくて書いていなかったのでそれと、近いうちにREADMEを書きます。
あと、適切でないパース時のエラー表示がまだ多いので、それを直していくつもりです。

最後に

Elixir v1.4はmix escript.installでhexやgithubからコマンドをインストールできるのが最高です。

*1:多分これ以外をやってもあんまり意味ない

*2:この再帰Enum.reduceなどで書いたらかなり読みづらいコードになるはず

*3:そもそも、これを無理やりパイプで書こうとするな

Reduxでstateをサーバー側に置く

qiita.com これの5日目の記事です。

概要

+--------+          +-------+                  +--------+
|        |  Action  |       |  Server Action   |        |
|        |--------->|       |----------------->|        |
| Client |          | Redux |                  | Server |
| (View) |  State   |       |  Patch / Action  |        |
|        |<---------|       |<-----------------|        |
|        |          |       |                  |        |
+--------+          +-------+                  +--------+

これをやる。
実例としてxeejp/theme-boilerplateなどがある。

使うもの

  • jsondiffpatchとclone
  • サーバー側にAction送るやつ (redux-sagaやredux-logicなどで)
  • サーバー側でパッチ発行するやつ

できた(Reducerのみ)

gistfc322c1c1dc2d7877fbc06ef37f6262f
解説する必要もないくらい*1、やっていることは単純ですが一応。
'INITIAL_STATE'actionで初期状態を受け取って、後はひたすら'PATCH'actionで送られてきたパッチを適用する。
パッチを適用する前にcloneしないと、前stateが直接書き換えられてしまうので気をつける必要がある。*2
あとは、このreducerをcombineReducersなりなんなりに渡すイメージ。(2016/12/7追記)

最後に

非常に短く、内容も薄い記事になってしまった。

*1:そもそも記事にする必要すらない

*2:Object.assignを使って浅いcloneをしていたときは、ひどい目にあった

筋トレしましょう

www.adventar.org

これの二日目の記事です。

 


 

早速ですが筋トレはいいですよ。みんな筋トレしましょう。

家でずっと椅子に座っているようなインドアな人間が健康を維持するには、筋トレしかありません。*1

筋トレを始める前は肩甲骨周りの痛みに悩まされていたのですが、これがすっかり治りました。

恐らく、筋トレによって姿勢が改善されたからだと思います。

 

こんな感じで筋トレを推しながらも、実は9月の後半から、この12月までの間、1回も筋トレしてないです。

体力的にも精神的にも疲れていて、筋トレをする気力を失っていた感じです。*2

そこで気になるのが、筋肉がどれくらい落ちたのかなんですが、正直ほとんど落ちてません。

これは多分、筋トレしてからついた"普段の生活や姿勢の維持に必要な筋肉"に頼って生活するようになったからだと思います。*3

 

本当にどうでも良いような短い独り言でしたが、今から久しぶりに筋トレしようと思うので、ここらで終わります。

みなさんも筋トレで、筋繊維を太くしていきましょう。 

*1:あと、たくさん食べること

*2:プログラムとか作曲とかは結構やっていた

*3:逆に言うと最低限の筋肉がついていない状態だった

何故いまさら新しいSNSを作ったのか

この前の10/2にwww.agoraful.comを公開しました。

せっかく作ったので、なぜ作ったのかを適当に文章に残しておこうと思います。

TwitterとSlackを知っているという前提で書きます。

 

まず、このサービスの目的は「数十や百以上のネット上のコミュニティーで活動することを現実的にすること」です。

この記事で言う「コミュニティー」は以下の様なものを想定しています。

  • 何かしらのプログラム言語やライブラリ、エディタの使用者の集まり
  • あるアーティストに興味を持っている人の集まり
  • 「鹿児島の温泉を巡る会」みたいなやつ
  • 「ピュアイリュージョニスト達」みたいなやつ
  • 「肉体改造部」みたいなやつ
  • その他のオープンな集まり

また「活動する」は、少なくとも年に数回は、なにかしら書き込んだりするくらいのものを考えています。

 

まず設計についてですが、この目的を達成するには、主に以下のことに気をつける必要があると考えました。

  1. コミュニティーごとに顔を変えたい場合がある
  2. 人が多くなっても、まともに使えるか
  3. 面倒臭さを減らす

1の「コミュニティーごとに顔を変えたい場合がある」というのは、人によってはFacebookTwitter、匿名掲示板サイトなどで投稿する内容が違っていたり、Twitterで趣味ごとに別のアカウントを用意したりすることを言っています。

要するに、「実名アカウント」「オタク友達用アカウント」「18禁アカウント」みたいに分けて、それぞれで別人を装いたい人がいるということです。

Twitterで複数のアカウントを使う理由として、同じアカウントで様々な内容の投稿をするとターゲットが絞れないから、というものもあると思いますが、ここではそれは考えていません。

 

2の「人が多くなっても、まともに使えるか」は、人が増えすぎて、まともに欲しい情報を追うことができなくなっている感のあった、某プログラミング言語のSlackと某ライブラリのDiscordを見たことがあったのを元にしています。

Slackのチャンネルなどを増やして分散すればいいという話かもしれませんが、前述の2つはそれをやっていませんでした。それは、チャンネルを直感的に探せる状態を維持したかったのだと考えています。

というか、Slackはチーム用のツールとして、Discordはゲーム用のチャット・ボイスチャットツールとして作られたものらしいので、そもそもそのような状況は考えていないのでしょう。

 

3の「面倒臭さを減らす」というのは、多くの人がネット上のコミュニティーに参加するときの条件式として持っているだろう「参加の面倒さ < 参加したさ」の左側の変数を小さくすることによって、年に数回レベルの活動しかする予定のない人でも気軽に参加できるようにする意味があります。

具体的な面倒臭さとして、登録の面倒臭さ、使い方を覚える面倒臭さ、アカウントを管理する面倒臭さ、などが挙げられます。

 

そして、いろいろ考えた結果、サービスの概要は以下のようになりました。

  • 「Sign in with Google」などの外部サービスを使ってログイン
  • ユーザーと呼ばれるものを複数作って簡単に切り替えることができる
  • スレッド上で投稿する
  • グループは複数のスレッド・メンバー・小グループを持つことができる

かなりシンプルなので、あまり真新しさはないですが、この特徴が全部揃っているサービスはこれまでには無かったのではないかと思っています。

 

実装に関しては、以下の図(GitHubのコミット)を見る限りでは公開までに実質四、五ヶ月くらいかかったことになります。また、使ったフレームワークやツールなどについては、別記事で書こうと思います。

f:id:ryo12redstone:20161006215639p:plain

 

長くなりましたが、少しはこのサービスのコンセプトが伝わったのではないかと思います。コミュニティーを作るときに、このサービス上で運営することも選択肢の一つとして考えていただけると大変嬉しいです。

どうか、このサービスをよろしくお願い致します。?

 

最後に、部分部分の機能の実装を手伝ってくれたNotFounds (@NotFounds8080)と、ダメダメだったプロトタイプのデザインを廃して、随分と良いUIにしてくれたまつも (@mtm_shoya)には本当に感謝しています。

今すぐにでも報酬を支払いたいのですが、このサービスによる収支が現状マイナスしかないのもあって金銭的に厳しく、非常に心苦しい状態です。