14. 雑多な話題
本日の話題
新版EpisoPass
情報処理との闘い
ローカルファイルを撤廃
登録インタフェース
P5.jsの楽しみ
情報共有により広がる世界
インターネットの三大発明
村井純教授「インターネットの三大発明はTCP/IP、ウェブ、公開鍵暗号」=b.tokyo2019 〜暗号技術によって作り出されるインターネットの発展とつぎの基盤 - 仮想通貨 Watch
https://gyazo.com/64bf54e9388c0c4e737d7bef443e4860
EpisoPass
https://gyazo.com/52ff5f7d532bfe2f637d37b958734fe8 http://www.pitecan.com/p/Amazon_masui@pitecan.com.html
http://pitecan.com/p
増井のパスワード多数
「増井のパスワード」でググっても出る
EpisoQ
EpisoPass問題を簡単に作るコマンド
% npm install -g episoq
% episoq
問題プールから選択する
「情報処理との闘い」
学士会会報記事
/masui-gakushikai/情報処理との闘い
「情報処理」とは
コンピュータによる計算のこと?
情報処理との闘いは解決するか?
upload, goquick, episopass, ...
ローカルファイルの撤廃
重要データはすべてWebにある
Amazon S3, Dropbox, Google Drive, Box, ...
ローカルファイルは微妙なものばかり
どこかのパソコンにだけ入ってるデータはあるか?
ローカルファイルの例
貰い物のPDF
スキャンデータ
写真、ビデオ
ローカルファイルの問題
別のパソコンで見られない
分類が難しい
カテゴリ? 時期? 名前?
置き場所が確定していない
いろんなところに領収書があったりする
解決方法
微妙なファイルは全部アップロード
Scrapboxで管理
利点
ローカル管理のファイルがゼロになる
階層に悩む必要がない
これから実験する予定
写真管理
/masui-photosに全部管理
便利かつ面白い
デジカメ以前は不可能だった
登録インタフェース
ネット集権主義
重要情報はすべてネット上
個人情報
共有情報
ネット上のデータ登録方法が重要
ネット上の個人情報
メール (IMAP)
ファイル (Evernote, Dropbox, etc.)
メモ (Wiki)
予定表 (Wiki)
ブックマーク
ネット上の共有情報
ファイル (GitHub, GoogleDocs, etc.)
メモ (Wiki)
ブックマーク (はてブ)
変換辞書もこれからはWeb上
WikiIME
SocialIME
ATOK
Wiki上の変換辞書
https://gyazo.com/e4a1e9ad62df6c8b07ddd5b42fc0e08d http://Scrapbox.io/Gictionary/%E9%AB%98%E9%80%9F%E9%81%93%E8%B7%AF
デモ: Chaim
Chrome拡張機能で動作
辞書もプログラムもWebにあるようなもの
登録の敷居
検索は普及してきた
誰もがいつでもどこでもググっている
登録は敷居が高い
登録を簡単にする方法、登録情報を活用する方法が今後の課題
登録に注目すべき
検索の普及
現在は誰でもどこでも検索している
ググる
ページ内検索
書店、図書館
これは最近の現象
ひと昔前は誰も検索してなかった
検索システムのある場所にでかけていた
登録も状況は変わるかも?
検索/入力/登録
実は似たようなもののはず
別物と思われている
登録を普及させる方法
登録の敷居を低くする
自動登録 / 自動セーブ
検索と登録の統合
登録専用アプリケーション
登録の順序を変える
登録すると楽しいシステム
簡単登録
登録ブックマークレット
3memo / GoQuick
Gyazo
ブックマークレット
JavaScriptプログラムをブックマークとしてメニューに登録
メニューからブックマークを選ぶとJavaScriptプログラムが動く
登録ブックマークレット
はてな
本棚
3memo
3memo: 公開ブックマーク
ネット上のブックマーク
URLや文字列に短いURLを割り当て
c.f. TinyURL
ショートカット的に利用
デモ: 3memo
GoQuick: パーソナルな3memo
情報が他人に見えない
https://gyazo.com/a7cad24bdebab4107bd84368425547dc
デモ: GoQuick
本棚.org
Web上で書籍情報共有
http://gyazo.com/4401b49e940bb988040ec683a225ef3e.png
本棚.orgの登録ブックマークレット
code:hondana.js
javascript:var src=document.location.href+
document.body.innerHTML;
re=new RegExp('(product|ASIN)/(0-9{9}0-9X)');
if(src.match(re)){void(window.open(
'http://hondana.org/%E5%A2%97%E4%BA%95/add?isbns='+RegExp.$2))};
デモ: 本棚.orgへの登録
Gyazo
画像を楽々アップロード
自動登録機能追加 (2015/6)
http://gyazo.com/ http://gyazo.com/23cc49972359958068281742189be6de.png
Gyazoの自動登録機能
画面クリップ時にメタデータを登録
時刻
アプリ名
URL
ページタイトル
連想検索で利用
IvySearch
http://gyazo.com/997642f12b6649a8b4586d68ecb4f5cb.png
Gyazoの「芋蔓検索」
TechCrunch記事
デモ: IvySearch
「神戸」
「記事」
「請求書」
Gyazoのコメント登録
面倒だと思われることが多い
ファイル名を考える方が面倒なのに?
自動登録 / 自動セーブ
大抵のアプリケーションやサービスでは自動セーブを行なわない
明示的にセーブ操作が必要
これは昔の名残
なんでも自動セーブ / 自動的登録すると便利
エディタの自動セーブ
Emacsのauto-save-buffers
デモ: Emacsの自動セーブ
Wikiの自動セーブ
編集結果を自動セーブすると楽
Scrapboxはすべて自動セーブ
URLの自動セーブ
閲覧したページを全部記録
Webページ閲覧の統計
何パーセントぐらいのページを再訪しているか?
Webページ閲覧の統計
何パーセントぐらいのページを再訪しているか?
アクセスの<strong>2/3</strong>は以前見たページの再訪
増井の場合
1日平均約600ページ
2/3は以前に見たページ
SNSなど以外は100ページ程度
本当に新しいページを見るのは30ページ程度
全部自動記録してもたかがしれている
何故自動セーブ/登録しないのか?
貧乏根性のせい
一生休まず文字入力しても10GBぐらい
なんでも全部セーブしても全然問題ない
検索と登録
3memo, GoQuickの場合
XYZ! で登録モード
XYZ で呼び出し
登録されていない場合はGoogle検索
検索と登録の融合
入力/検索/登録は普通は別システム
e.g. 単語の入力/検索/登録
検索操作と登録操作をシームレスにしたい
Gyaimの単語登録手順(1)
登録したい単語をコピー
単語の読みを入力
登録したい単語が候補に出る
候補を選択すると登録完了
Gyaimの単語登録手順(2)
単語の読みを入力
ググった結果が候補に出る
候補を選択すると登録完了
デモ: Gyaimの単語登録
Gyaimの単語登録
検索結果を例示
一種の例示インタフェース
検索結果にエントリを加える = 登録
様々な検索システムに登録機能を融合可能
e.g. 画像検索結果に新たな画像を加える
P5.jsの楽しみ
https://p5js.org/ https://gyazo.com/42aa53c84d93659034f52370ca11e427
ProcessingのJavaScript版
四文字熟語クイズ
https://runp5.com/?code=https://scrapbox.io/api/code/masui/四文字熟語データ/fourdata.js,https://scrapbox.io/api/code/masui/四文字熟語クイズ/four.js&css=https://fonts.googleapis.com/css?family%3dKosugi%20Maru https://gyazo.com/a1c05a95c84a8a33d3934be7928ae6df
/masui/四文字熟語クイズ
P5.jsを動かす
スタンドアロン版
(将来なくなる可能性あり)
ブラウザで動かすことが推奨
ドキュメントとサンプル
P5.js reference
https://gyazo.com/c096a74372317bcfef987fb1a95e92a5
チュートリアル
Tutorial
Examples
P5.jsの書籍
P5 book (松田)
https://images-fe.ssl-images-amazon.com/images/I/51DCOj5HYVL._AC_US320_FMwebp_QL65_.jpg
サンプル多数
Creative Coding and Data Visualization with p5.js
https://images-na.ssl-images-amazon.com/images/I/61wLQ8X0G-L._SX379_BO1,204,203,200_.jpg
P5をScrapboxで動かす
コード記法でプログラムを記述
code:test.js
alert('abc');
Execute
Create a link for running it
https://runp5.com/ を利用
Source: https://github.com/masui/runp5
FireBase利用
「文芸的プログラミング」スタイル
例: 正規分布の生成
https://gyazo.com/edbeca3c66ed7606e6fcc27dbf9b5bc8
Execute
code:normal.js
// Adding 10 random numbers and show the distribution
function setup(){
createCanvas(400,400)
histogram = []
for(i=0;i<100;i++) histogrami = 0
strokeWeight(0)
}
function draw(){
val = 0
for(i=0;i<10;i++) val += random(1/10)
histogramMath.floor(val * 100) += 1
fill('#ff0')
rect(0,0,400,400)
fill('blue')
for(i=0;i<100;i++)
rect(i*4,400-histogrami,4,histogrami)
}
例: 結城氏のプログラム
https://gyazo.com/86adfa800b4f9976fdfe65613c54593c
Execute
code:yuki.js
T=0
function setup(){
createCanvas(600,600)
noStroke()
}
function draw() {
fill('#000')
rect(0,0,600,600);
N=100
S=300
for (n=1; n<N; n++) {
r=n*2
fill('#fff')
R=(N-n)/10
t=T*n
ellipse(S+r*cos(t),S-r*sin(t),R,R)
T+=0.00001
console.log(T)
}
}
例: 山辺氏のプログラム
https://gyazo.com/0f86aad2c6be7650ad8a4ceea95b5d7f
Execute
code:rz.js
function setup(){
createCanvas(600,600);
background(128);
}
function draw(){
x = random(0,width);
y = random(0,height);
w = random(2,20);
noStroke();
if(x % 60 < 35)//xを60で割った余りが35未満だったら
fill(0,0,0);
else
fill(255,255,255);
ellipse(x, y, w, w);
}
Hello World
code:hello.js
alert('Hello, world!');
Execute
https://runp5.com/sfc-web2019/14._雑多な話題/hello.js
数値計算
$ \sqrt{2}
code:sqrt.js
value = 100
for(;;){
alert(value)
value = (value + 2/value) / 2
}
Execute
特殊関数
setup()
初期化
draw()
フレームごとに呼ばれる
線の描画
Execute this code
code:line.js
function setup(){
line(0,0,100,100);
}
矩形描画
Execute this code
code:rect.js
function setup(){
rect(10,10,80,80);
}
矩形描画
Execute
code:boldrect.js
function setup(){
stroke(255, 255, 0); // yellow
strokeWeight(10);
rect(10,10,80,80);
}
矩形描画
Execute
code:fillrect.js
function setup(){
fill('#00f'); // blue
rect(10,10,80,80);
}
円描画
Execute
code:circle.js
function setup(){
ellipse(50,50,30,30);
}
Using draw()
Execute
code:randrect.js
function setup(){
createCanvas(400, 400)
strokeWeight(0)
}
function draw(){ // called 30? times in a second
fill('blue')
posx = random(0,400)
posy = random(0,400)
rect(posx,posy,10,10)
}
Using draw()
Execute
code:randrect2.js
function setup(){
createCanvas(400, 400)
strokeWeight(0)
}
function draw(){
clear()
fill('blue')
posx = random(0,400)
posy = random(0,400)
rect(posx,posy,10,10)
}
Using mouse position
Execute
code:mouse.js
function setup(){
createCanvas(600, 600)
}
function draw(){
clear()
stroke('blue')
line(0,0,mouseX,mouseY) // predefined mouse coordinates
}
Getting mouse event
Execute
code:mouseevent.js
var value = 0;
function draw() {
fill(value);
rect(25, 25, 50, 50);
}
function mousePressed() {
if (value == 0) {
value = 255;
} else {
value = 0;
}
}
Drawing circles
https://gyazo.com/0ec9a6ad4dc1f39c260d34439bf827a8
Execute
code:drag.js
function setup() {
createCanvas(400,400);
fill(0);
}
function mouseDragged(){
ellipse(mouseX, mouseY, 20, 20);
}
Mouse move event
Execute
code:follow.js
function setup(){
createCanvas(400,400);
}
function draw(){
clear();
fill(0,0,255);
rect(mouseX,mouseY,40,40);
}
Drawing a fractal tree
Execute
code:tree.js
// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com
// Recursive Tree
// Renders a simple tree-like structure via recursion
// Branching angle calculated as a function of horizontal mouse position
var theta;
function setup() {
createCanvas(640, 360);
}
function draw() {
background(51);
// Let's pick an angle 0 to 90 degrees based on the mouse position
theta = map(mouseX,0,width,0,PI/2);
// Start the tree from the bottom of the screen
translate(width/2, height);
stroke(255);
//branch(120);
branch(mouseY); // Y座標で深さを変えるようにしてみた
}
function branch(len) {
// Each branch will be 2/3rds the size of the previous one
var sw = map(len,2,120,1,10);
strokeWeight(sw);
//strokeWeight(2);
line(0, 0, 0, -len);
// Move to the end of that line
translate(0, -len);
len *= 0.66;
// All recursive functions must have an exit condition!!!!
// Here, ours is when the length of the branch is 2 pixels or less
if (len > 2) {
push(); // Save the current state of transformation (i.e. where are we now)
rotate(theta); // Rotate by theta
branch(len); // Ok, now call myself to draw two new branches!!
pop(); // Whenever we get back here, we "pop" in order to restore the previous matrix state
// Repeat the same thing, only branch off to the "left" this time!
push();
rotate(-theta);
branch(len);
pop();
}
}
エスカレータのシミュレーション
Execute
code:escalator.js
STRATEGY1 = 0; // left
STRATEGY2 = 1; // right
lspeedfactor = 1.0;
lgapfactor = 1.0;
rspeedfactor = 2.0;
rgapfactor = 3.0;
strategy = STRATEGY2;
var pair = location.search.substring(1).split('&');
for(var i=0; pairi; i++){
var kv = pairi.split('=');
if(kv0 == 'ls') lspeedfactor = kv1;
if(kv0 == 'lg') lgapfactor = kv1;
if(kv0 == 'rs') rspeedfactor = kv1;
if(kv0 == 'rg') rgapfactor = kv1;
}
MOVING_LOWER = 0;
WAITING_LOWER = 1;
ASCENDING = 2;
UPPER = 3;
LEFT = 0;
RIGHT = 1;
llane = 220.0;
rlane = 250.0;
escheight = 460.0;
WINWIDTH = 500;
WINHEIGHT = 500;
NPERSONS = 50;
NSTAIRS = 15;
STAIRHEIGHT = 60;
STEPUNIT = 1;
steppos = 0;
waiting_l = 0;
waiting_r = 0;
done = false;
xspeed = 1.0;
persons = [];;
loops = 0;
var Person = function(){
this.x = 0.0;
this.y = 0.0;
this.status = MOVING_LOWER;
this.lr = LEFT;
};
function setup(){
createCanvas(WINWIDTH,WINHEIGHT);
frameRate(60);
for(var i=0;i<NPERSONS;i++){
personsi = new Person();
}
}
function can_ascend_l(n){
var result = true;
for(var i=0;i<n;i++){
if(personsi.status == ASCENDING &&
personsi.lr == LEFT &&
personsi.y - personsn.y < STAIRHEIGHT * lgapfactor){
return false;
}
}
return true;
}
function can_ascend_r(n){
for(var i=0;i<n;i++){
if(personsi.status == ASCENDING &&
personsi.lr == RIGHT &&
personsi.y - personsn.y < STAIRHEIGHT * rgapfactor){
return false;
}
}
return true;
}
function can_forward_lower(n){
for(var i=0;i<n;i++){
if(personsi.status == MOVING_LOWER &&
personsi.x - personsn.y < 30.0){
return false;
}
}
return true;
}
function can_forward_upper(n){
for(var i=0;i<NPERSONS;i++){
if(personsi.status == UPPER &&
personsi.x - personsn.x > 0.0 &&
personsi.x - personsn.x < 30.0){
return false;
}
}
return true;
}
function all_upper(){
for(var i=0;i<NPERSONS;i++){
if(personsi.status != UPPER) return false;
}
return true;
}
function draw(){
if(done) return;
background(213,200,255);
for(var i=0;i<NSTAIRS;i++){
y = i * STAIRHEIGHT + steppos;
//line(llane-10+10,WINHEIGHT-y,rlane+10+20+10,WINHEIGHT-y);
fill(200,200,200);
strokeWeight(0);
rect(llane-10+10,WINHEIGHT-y,rlane-llane+40,STAIRHEIGHT/2);
}
steppos += STEPUNIT;
if(steppos >= STAIRHEIGHT){
steppos = 0;
}
for(var i=0;i<NPERSONS;i++){ // 駒をひとつずつ進める。
switch(personsi.status){
case MOVING_LOWER: // 下で移動中
if(personsi.x >= llane && // 左レーンまでたどりついたとき
personsi.lr == LEFT){
if(strategy == STRATEGY1){
if(waiting_l == 0 || waiting_l < waiting_r){
personsi.status = WAITING_LOWER;
personsi.x = llane;
waiting_l++;
}
else {
personsi.lr = RIGHT; // 右で待つことにする
}
}
else if(strategy == STRATEGY2){
if(waiting_l < waiting_r){
personsi.status = WAITING_LOWER;
personsi.x = llane;
waiting_l++;
}
else {
personsi.lr = RIGHT; // 右で待つことにする
}
}
}
else if(personsi.x >= rlane && // 右レーンまでたどりついたとき
personsi.lr == RIGHT){
personsi.status = WAITING_LOWER;
personsi.x = rlane;
waiting_r++;
}
if(can_forward_lower(i)){ // 前に進める場合は一歩前に移動する
personsi.x += xspeed;
}
break;
case UPPER: // エスカレータからおりていて
if(can_forward_upper(i)){ // 前に進める場合は一歩前に移動する
personsi.x += xspeed;
}
break;
case WAITING_LOWER: // エスカレータ待ち状態で、
if(personsi.lr == LEFT && // 左で待っていて
can_ascend_l(i) // 上に余地がある
){
personsi.status = ASCENDING;
waiting_l--;
}
else if(personsi.lr == RIGHT && // 右で待っていて
can_ascend_r(i) // 上に余地がある
){
personsi.status = ASCENDING;
waiting_r--;
}
break;
case ASCENDING: //エスカレータに乗っていたら
if(personsi.y >= escheight){ // エスカレータで上まで到達していればおりる
personsi.status = UPPER;
personsi.y = escheight;
}
else {
if(personsi.lr == LEFT){
personsi.y += STEPUNIT * lspeedfactor; // 1段上に移動する
}
else {
personsi.y += STEPUNIT * rspeedfactor; // 1段上に移動する
}
}
break;
}
}
strokeWeight(1);
for(var i=NPERSONS-1;i>=0;i--){
fill(255,255,0);
rect(personsi.x+10,WINHEIGHT-30-personsi.y,20,20);
fill(0,0,0);
text(i+1,personsi.x+10+3,WINHEIGHT-30-personsi.y+14);
}
if(! all_upper()){
loops++;
}
else {
done = true;
}
fill(0,0,0);
// text(millis(),20,20);
text(loops,20,20);
}
音を出す
Execute
code:sin.js
// canvas is not created if setup() is not defined
freq = $('<div>').text('440').appendTo($('body')) // div for freq
freqval = 440;
osc = new p5.TriOsc(); // set frequency and type
osc.amp(0.5);
osc.start();
$('<div>').appendTo($('body')).slider({ // jQuery UI slider
min: 50,
max: 1200,
value: 440,
slide: (event, ui) => {
freqval = ui.value
osc.freq(freqval)
freq.text(freqval)
osc.start()
}
});
情報共有により広がる世界
重要情報をみつける方法
認証局を使わずに情報の存在を証明
重要なファイルとは?
× 動画ファイル
× システムファイル
× MP3
○ 自分が撮った写真
○ アイデアメモ
サイズやファイル属性から判定できない
重要なファイルの特徴
自分だけが持っているファイルは重要
○ 自分が撮った写真
○ アイデアメモ
重要度の判定
ファイルのハッシュ値を登録サイトに登録
自分以外に誰も登録していないものは重要
他人とのファイル共有の視覚化
http://gyazo.com/5124de74689ff55d53ffb3da92c1c636.png
自分のディスク内の重複ファイル
http://gyazo.com/4418725289623822fa490081d48ec670.png
HashInfo.com
手持ちのファイルのハッシュと属性を登録
ユーザが増えると重要度を判定できるようになる
情報の存在証明
公証役場を利用
認証局を利用
手間と金がかかる
登録による存在証明
証明したいファイルのハッシュを計算
e.g. 0a1b2c3d
それを含むURLを生成
e.g. http://example.com/0a1b2c3d
ソーシャルブックマークに登録
はてなブックマーク
del.ico.us
ソーシャル存在証明
F = 存在を証明したいファイル
ある時点において F が存在したことを証明したい
authコマンド
F: 存在を証明したいファイル
H ← F のハッシュ (e.g. 0a1b2c3d)
U ← H含むURL (e.g. http://3memo.com/masui/0a1b2c3d)
S ← 保護されたURL (e.g. http://pitecan.com/secret)
F を S にコピー
S を U に登録
U を各種SBMに登録
存在証明
U はあちこちに登録されている
タイムスタンプも登録されている
Uの偽造は不可能
F が存在しない時点で U を登録することは不可能
⇒ U が登録されている時点で F が存在したことがわかる
ソーシャル存在証明
アイデア段階
裁判などで勝てるかどうかは不明
共有しつつ情報を保持する方法
ステガノグラフィー
大事なものを共有するときはステガノグラフィーが有用なことも?
ステガノグラフィー
秘密データを普通のデータ中に埋め込む
暗号化したことが一見わからないようにする
ステガノグラフィー例
オリジナル画像
http://masui.org.s3.amazonaws.com/2/2/225079322c2281a0d9c2698e34b07d7c.jpg
ステガノグラフィー例
40バイトのデータを埋め込んだもの
http://masui.org.s3.amazonaws.com/0/0/00a809645da912a650563f5de08a761e.jpg
ステガノグラフィー例
200バイトのデータを埋め込んだもの
http://masui.org.s3.amazonaws.com/3/2/32238e884aad99a08526690fe428a809.jpg
漫画への情報埋め込み
http://gyazo.com/e09556d75f21d725b6751683ae015e99.png
漫画への情報埋め込み
集中線などにデータを埋め込めば良い?
http://gyazo.com/a6027ae7fa53f4c4cab05cfaf36abf95.png
まとめ