Tシャツをデザインしてみました

昔からTシャツが好きですが、最近、自分でデザインしてみてもいいのでは?と思うようになっ(てしまいまし?)た。
第一成果物はこちらです: ハッカーのおそれあり

ハッカーのおそれあり

第二成果物も出しました: マジレス乙

I’ve decided to start creating t-shirts. They’ll mostly be in Japanese though, and it seems like this site doesn’t do international deliveries. :< I wonder if it would be worth it to sell Japanese t-shirts on e.g. American services…

クックパッドで見つけた美味しいレシピ、和風&洋風のミックスの編

今年(2016年)の1月から、クックパッドのプレミアム会員です!
今まで見つけた美味しいレシピを共有してもいいのでは?と思って〜
並び順はおすすめ順かな?適当な場合もあるかもしれませんが…
今回は、和風&洋風のミックスの編です!一番わくわくするカテゴリじゃありませんか?^^
和風編はこちらへ
中華編はこちらへ
カレー編はこちらへ

洋風編はこちらへ

http://cookpad.com/recipe/3432724 自宅で作る基本のミートソース
神レシピ!
味噌、料理酒、かつおだし、豚肉が主人公。
パスタよりも、カレーと同じように、ご飯にかけて食べた方が美味しいと思います!
さっきも食べました。これを食べて、この記事を書こう!と思いつきました!
2017年1月30日追記: ほうれん草とかも合います。

http://cookpad.com/recipe/3678114 簡単すぎるトマトクリームうどん
マイルドな味わいで美味しかったです。
作った時のメモによると、うどん400 g、ウインナー 90 gを使用していました。
他のパスタものもうどんで作ってみたいなぁと思います!

http://cookpad.com/recipe/2814803 簡単☆ピザ生地(照り焼きチキン)
美味しいです^^

クックパッドで見つけた美味しいレシピ、洋風編

今年(2016年)の1月から、クックパッドのプレミアム会員です!
今まで見つけた美味しいレシピを共有してもいいのでは?と思って〜
並び順はおすすめ順かな?適当な場合もあるかもしれませんが…
今回は洋風編です。
和風編はこちらへ
中華編はこちらへ
カレー編はこちらへ

http://cookpad.com/recipe/1192653 スウェーデン・レンズ豆のスープ
ヨーロッパでよく食べました!

http://cookpad.com/recipe/2105902 我家の定番ツナベーコントマトパスタソース
そんなに特別なものではないですが、美味しいです^^
塩を減らしてコンソメを入れる時もありますが、意外となくてもいけます!

http://cookpad.com/recipe/1753696 *アボカドとツナのレモン醤油サラダ*
サンドイッチに挟んで食べました。

クックパッドで見つけた美味しいレシピ、カレー編

今年(2016年)の1月から、クックパッドのプレミアム会員です!
今まで見つけた美味しいレシピを共有してもいいのでは?と思って〜
並び順はおすすめ順かな?適当な場合もあるかもしれませんが…
今回はカレー編です。
和風編はこちらへ
中華編はこちらへ

http://cookpad.com/recipe/252807 簡単☆チキンカレー(中毒性あり)
美味しいです〜
手羽先ではなく、もも肉で作りました。
ちょっとは、コンソメなどを入れてもいいと思います!

http://cookpad.com/recipe/529993 レポ1000人感謝●簡単本格ナン●
なんですか?そんなに本格的ではないですが、おいしいですよ!
本格的でないのは、オーブントースターで作っているからかもしれません…
ちなみに、生地を作りすぎて、余った生地を一日くらい冷蔵庫に入れたら、結構大きくなったのですが、美味しかったです。その時はカレー用のナンではなく、サンドイッチにしました。

http://cookpad.com/recipe/2000611 カレー焼きそば
焼きそばならこれがおすすめです。ただし少し飽きやすいかもしれません…

クックパッドで見つけた美味しいレシピ、中華編

今年(2016年)の1月から、クックパッドのプレミアム会員です!
今まで見つけた美味しいレシピを共有してもいいのでは?と思って〜
並び順はおすすめ順かな?適当な場合もあるかもしれませんが…
今回は中華編です。
和風編はこちらへ

http://cookpad.com/recipe/2730789 トマトと卵の中華炒め
中国に住んでいたことがありますが、これはよく出ていました!

  • 仕上げに、米酢を入れます!(小さじ2杯は既に少し多いかもしれません)
  • お弁当には向いていないです。卵とトマトは半熟くらいが美味しいです!
  • 中華スープの素は、顆粒のものを使った方が良いです。私はウェイパーで作っていますが、ウェイパーだと、溶けにくいです。
  • 中国で食べたものは、トマトと卵以外の具は入っていませんでした。

http://cookpad.com/recipe/2563740  ウェイパァーでふわふわ卵のレタススープ

私は肉は入れません。
簡単ですし、すごく中華って感じのスープで、外国人も大喜びしてくれます!

http://cookpad.com/recipe/837544 濃厚ウマ辛♪坦々麺
最近は作っていないですが、お店のよりも美味しいですよ^^
中国の担々麺はだいぶ違うから…中華でいいのかな?
作業タイミング的には、なかなか難しいかもしれません。全部合せておいてから作った方が良いです!

http://cookpad.com/recipe/2183021 簡単ズボラ、味は本格★チンジャオロース
美味しいです^^

クックパッドで見つけた美味しいレシピ、和風編

今年(2016年)の1月から、クックパッドのプレミアム会員です!
今まで見つけた美味しいレシピを共有してもいいのでは?と思って〜
並び順はおすすめ順かな?適当な場合もあるかもしれませんが…

http://cookpad.com/recipe/2588173 簡単☆小麦粉で作るチーズお好み焼き
お好み焼きを作る時は、いつもこのレシピです。
ただし、これだと、少し分厚いかもしれません。
ほんだしは、もうちょっとだけ濃くしてもいいかもしれません。

http://cookpad.com/recipe/2407781 もっちり美味しい♡ニラの薄焼き
初めてのつくれぽを付けたレシピです!
美味しい&安いです!
飽きやすいかもしれませんが、難しくないので初めてでも成功する逸品です!

http://cookpad.com/recipe/2348826 エリンギの帆立風!にんにくバター醤油焼き
ちなみに、これを、豚醤油というもので作ったのですが、大変美味しかったです。
豚醤油は、http://ccib.or.jp/?page_id=308で購入できます。
高いです(´・ω・`)
他のブログなどを見てみたら、たまにお店でも買えることがあるらしいです!最初にメールで、どこか首都圏のお店では購入できませんか、と問い合わせてみましたが、現在できないということで、メールで注文して着払いで払いました。

http://cookpad.com/recipe/2921320 大根と合挽き肉の甘煮
美味しいです^^
「これが日本の味ですよ」と外国人に出すのに良い逸品だと思います!

http://cookpad.com/recipe/2839788 ♡レンコンと秋刀魚の黒酢あんかけ♡
きれいだし、美味しいです^^
ただし、秋刀魚ではなく、チキン竜田で作りました。

http://cookpad.com/recipe/1374729 手作り和風ドレッシング☆
簡単な和風ドレッシングです。美味しいです^^

Mixiのライフサイクルイベントの署名付きリクエスト / Mixi Lifecycle Event OAuth signatures

Mixiのライフサイクルイベント(アプリが追加された、アプリがマイアプリから削除されたといったイベント)の署名付きリクエストは他のよりまた少し違うみたいです。公開鍵を使うところは他にもありますが、ライフサイクルイベントの場合は、OAuth情報がHTTPのAuthorizationヘッダーに入っているため、お使いのOAuthライブラリーによってうまくいかない場合があるかもしれません。Rubyのoauthではほぼ動くのですが、

xoauth_signature_publickey=lc_20131107

が署名に含まれないため失敗します。

signature = OAuth::Signature.build(request, {:parameters => {'xoauth_signature_publickey' => 'lc_20131107'}}) do

のようにOAuth::Signature.build()に渡すと署名に含まれ、署名の検証が通ります。

検証が通ったbase stringの例:

GET&http%3A%2F%2FXXXXXXXXXX%2FXXXXXXXXXX%2FXXXXXXXXXX%2Faddapp&eventtype%3Devent.addapp%26id%3Dmo3XXXXXXX7fr%26mixi_invite_from%3DmgwXXXXXXXnt8%26oauth_consumer_key%3Dmixi.jp%26oauth_nonce%3D719445958eb7ae359824%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1468335606%26oauth_version%3D1.0%26opensocial_app_id%3D41345%26xoauth_signature_publickey%3Dlc_20131107

ちなみに、xoauth_signature_publickeyが一生変わらないわけではありません。Mixiの公開鍵と同じタイミングで変わる予定です。現在使われている公開鍵の有効期限は確か2020年だったと思いますので、まだしばらく大丈夫かもしれないですね。

英訳の下のmixi_signed_request?関数の例もご参照ください。

Mixi’s Lifecycle events (add app and remove app) use an OAuth scheme that is slightly different from Mixi’s other OAuth implementations: the OAuth headers are included in the HTTP Authorization header. Depending on your OAuth library,  the non-standard xoauth_signature_publickey (passed in the HTTP header) may not be included when calculating the signature. However, Mixi includes this parameter. You’ll have to pass it manually to OAuth::Signature.build(), e.g., like this:

signature = OAuth::Signature.build(request, {:parameters => {'xoauth_signature_publickey' => 'lc_20131107'}}) do

Here’s an example of a base string that could pass validation:

GET&http%3A%2F%2FXXXXXXXXXX%2FXXXXXXXXXX%2FXXXXXXXXXX%2Faddapp&eventtype%3Devent.addapp%26id%3Dmo3XXXXXXX7fr%26mixi_invite_from%3DmgwXXXXXXXnt8%26oauth_consumer_key%3Dmixi.jp%26oauth_nonce%3D719445958eb7ae359824%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1468335606%26oauth_version%3D1.0%26opensocial_app_id%3D41345%26xoauth_signature_publickey%3Dlc_20131107

Note that the certificate and the “lc_20131107” are linked. When there is a change, both will be updated. The current certificate is valid until 2020 or so.

The full verification code could look like this:

  def mixi_signed_request?
    mixi_certificate = <<END
-----BEGIN CERTIFICATE-----
MIIDNzCCAh+gAwIBAgIJAIQ3zDiILtpzMA0GCSqGSIb3DQEBBQUAMDIxCzAJBgNV
BAYTAkpQMREwDwYDVQQKDAhtaXhpIEluYzEQMA4GA1UEAwwHbWl4aS5qcDAeFw0x
MzExMDcwODQwNTBaFw0yMzExMDUwODQwNTBaMDIxCzAJBgNVBAYTAkpQMREwDwYD
VQQKDAhtaXhpIEluYzEQMA4GA1UEAwwHbWl4aS5qcDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMxzCu9sUctGAzL/X0/sH2MSRmc/+X2Wx87ObZDpEd5P
19mIUQXW6hCXObB3SkE7kMuXiRhtrxwsnB9fjYIUEq/1vsTHkLJoJVUFIumqe6EH
c/WZaTmu34WpEUFXNDS4htidXyVqikoDQZF9wdczyH7bLPbekQfRAcyek3E6/7Qi
B00yWUqK8FcUOD4ILmtSHXsz4BNqekNgEzfUi5WkBYKtuD5zSunZalbWUPS7xa57
o1auVdclaHBfqe8dC5DTbxIe0szpHckQrJF9fJ/bIQSmvY6ADBRGfoLF7Fgoc5x+
R5my9weytzg4WdDUjYrxmhy5IpjxytipQqrFDqAUxl8CAwEAAaNQME4wHQYDVR0O
BBYEFKCQSlssCWLqd0tT7NVtoBUNzCasMB8GA1UdIwQYMBaAFKCQSlssCWLqd0tT
7NVtoBUNzCasMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBALoI7elk
ZCv+pUpi6aJepzLnQDYHB2eXpDkpWEUrF1WMvx8ovmWdVeviHqUdFtGL0XZ5tSoV
vGE/KQTavag+MfbafKaff4iHXNyNMygeFP7r/FaFQQRafyNfhaXF6sWfwKrOk/Bc
jIXFN9tYWN6LEwNgYT0C+OSOppQJzt2y1am15FExAHQcIEFYc+3T+MGGJ7e9H8tn
Qz84WmIgNZRUMYQC0PJTsMNVvr+/DTIzjabKz4W8qodXGA7AxXiRYdgC+3RUj/rA
lR09PXZ6nRaKiB0KBDIMUlPu/0u0Vw+GBt0ckH0htOKSxsn09jkITFhy3NX7Slbk
jlnY4pS9JO+avmM=
-----END CERTIFICATE-----
END

    require 'oauth'
    require 'oauth/signature/rsa/sha1'
    begin
      consumer = OAuth::Consumer.new(nil, mixi_certificate, {:signature_method => 'RSA-SHA1'})
      signature = OAuth::Signature.build(request, {:parameters => {'xoauth_signature_publickey' => 'lc_20131107'}}) do
        [nil, consumer.secret]
      end
      return signature.verify
    rescue => e
      logger.debug(e.inspect)
      return false
    end
  end

さくらクラウドの料金システムについて / Sakura’s Cloud Pricing System

さくらクラウドの料金システムには、月額、日額、時間額と、3つの価格があります。月額が日額などよりもお得であることは、プラン変更の際に頭に入れておいた方が良いかもしれません。
損をする例を見てみましょう:
プラン/2Core-2GB   30 + 0時間   3,240円 ← 高いスペックで通常の月額
プラン/2Core-2GB   17 + 14時間   2,916円 ← 高いスペックで17日間分
プラン/1Core-1GB   12 + 9時間   982円 ← 安いスペックで12日間分
12日間スペックが低かったのに、3898円と、高いスペックの通常の月額より658円高いです。
皆さん、気をつけてください。

Just here to document a peculiar feature of Sakura Cloud’s pricing system.
Let’s say you’ve been running on high-spec’d servers and want to reduce these specs a bit. For example, you would like to go from プラン/2Core-2GB down to プラン/1Core-1GB.
Depending on the day you do the change, you may end up paying more than necessary. Here’s an example:
プラン/2Core-2GB    30 + 0時間    3,240円 ← This is the normal monthly price for 2 core/2 GB plan
プラン/2Core-2GB    17 + 14時間    2,916円 ← Let’s say you reduced the specs on the 17th – you’ll pay almost a month’s worth of server fees for the 2 core/2 GB plan
プラン/1Core-1GB    12 + 9時間    982円 ← And the remaining days for the 1 core/1 GB plan
So that month you’ll pay 3898 JPY, even though you were running on lower specs.

Mixiの(モバイルでの)署名付きリクエスト

この度、ガラケー向けのMixiアプリを作ることになりました。こういうアプリのリクエストは、実機 → Mixiが運営しているサーバー → アプリ用サーバー、という流れで送られるようです。(もちろんサーバーから実機への回答は逆の流れです。)Mixiのサーバーは、各リクエストに、ユーザーのMixi IDみたいな文字列を付けてくれて、そして本当にMixiのサーバーから来たリクエストかどうかを検証できるように、署名も付けてくれます。

Mixiの公式ドキュメンテーションはhttp://developer.mixi.co.jp/appli/spec/mob/validate-oauth-signature/にありますが、残念ながら、現在のところ、多少足りない部分がありまして…

まずは、下記のGETリクエストを例として上げているのだが、

http://example.com/foo/?opensocial_app_id=123&opensocial_owner_id=xxxxxxxx

「Ky/6LlDHpHX1EZMRi5mfUl9vxqY=」という署名になるには、「opensocial_owner_id」を「xxxxxxxx」ではなく、「456」に設定しないといけません。
なんで知ってるの!?
archive.orgのおかげです: https://web.archive.org/web/20100912034001/http://developer.mixi.co.jp/appli/spec/mob/validate-oauth-signature

続いて、「特殊な文字(漢字など)を含んでいるパラメーターはどうすればいいですか?」という質問に対する明らかな答えもなく、困っていました。
いろいろ試したところ、二重エンコーディングで対応できました。
つまり、「example.com/foo?test=テスト」みたいなリクエストは、ユーザー側のブラウザーから「example.com/foo?test=%E3%83%86%E3%82%B9%E3%83%88」のように送られます。それを「%25E3%2583%2586%25E3%2582%25B9%25E3%2583%2588」にすると検証が通ります。

test[foo]=barみたいな、角括弧が入っているパラメーターも同じように二重エンコーディングします。

Ruby on Railsだと、下記のようなコードで検証できます。

def mixi_signed_request_mobile?
    require 'cgi'
    oauth_header = request.headers["HTTP_AUTHORIZATION"].split(/\s*,\s*/)
    oauth_header_hash = Hash[oauth_header.map { |keqv| keqv.gsub('"', '').split('=') }]

    base_string_array = [
      "oauth_consumer_key=" + @client_id,
      "oauth_nonce=" + oauth_header_hash["oauth_nonce"],
      "oauth_signature_method=" + "HMAC-SHA1",
      "oauth_timestamp=" + oauth_header_hash["oauth_timestamp"],
      "oauth_version=" + "1.0"
    ]
    if request.get?
      uri = URI.parse(request.url)
      query_array = URI.decode_www_form(uri.query)
      base_string_array += query_array.map{|param| "#{CGI.escape(param[0])}=#{CGI.escape(param[1])}"} # takes care of opensocial_app_id and opensocial_owner_id as well
    else
      # don't need the actual parameters for post requests (mixi-specific awkwardness)
      base_string_array += ["opensocial_app_id=#{params["opensocial_app_id"]}", "opensocial_owner_id=#{params["opensocial_owner_id"]}"]
    end
    base_string_array.sort!
    url = request.original_url.gsub(/\?.*/, '') # can't use request.base_url + request.path because the trailing slash is sometimes(?) cut off
    baseString = request.method + "&" + CGI.escape(url) + "&" + CGI.escape(base_string_array.join("&")) # [] and utf-8 are doubly percent-encoded!! e.g. "テスト" becomes "%25E3%2583%2586%25E3%2582%25B9%25E3%2583%2588"!!!!!

    sha1 = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA1.new, @client_secret + "&", baseString)
    base64 = Base64.strict_encode64(sha1)

    return CGI.escape(base64) == oauth_header_hash["oauth_signature"]
  end

(The above explanation and code show how to verify Mixi’s OAuth 1.0 signatures, as used with Japanese feature phone apps.)