看護学生、コロナに感染する。

8/16(火) 発症日
いつもよりもなんとなく体がだるいような感じがする。ソファーで一日寝て過ごした。

8/17(水) 2日目
昨日に増して倦怠感が強い。機能と同じくソファーで一日寝て過ごした。二日連続で無駄にしたくない思いからか、夕方におもむろに起き上がってモンスターエナジー2本飲んでランニングへ出かける。このときはまだ咽頭通、発熱等の明らかな症状は無かった。

8/18(木) 3日目
朝から強い咽頭痛と微熱あり。無理して体を起こそうとするが強いふらつきがおこり、体調に明らかな異変が起きていることを自覚する。学校の課題をやらねばというプレッシャーから机に体を持っていくが、体の関節痛と酷い倦怠感でベッドへ倒れこむ。コロナかもと不安に思って母が入手してきてくれた簡易抗原キットで検査すると陽性だった。夕方には38.3℃まで上がり、背中や関節が痛くて何度も寝返りをうつほど苦しい夜を過ごした。
>

CとTの両方にマーカー(線)が引かれれば陽性らしい
< 

8/19(金) 4日目
朝一で近くの耳鼻咽喉クリニックへかけこむが忙しいようでなかなか対応してもらえず、午前中いっぱい車で待たされる羽目になった。この時の体温は37.0℃まで下がっており、前日の夜と比べると気分はとても良くなっていた。これ以降、再び熱が上がることはなかった。

8/20(土) 5日目
朝起きて体温を測ると36℃代まで戻っており気分はすっかり良くなっていた。学校の課題をやれるまでに回復していたので、体調には常に気を配りながら辛くならない程度に課題を進めていた。

8/21(日) 6日目
咽頭通はほとんどなくなり食欲も戻ってきたので親が買ってきてくれたウナギを食べた。味覚、嗅覚等の後遺症もなく、もうほとんど全回復状態。

まとめ
普段から看護教員に床にモノを置くなと散々言われてきたがいまいちピンとこなかった。コロナ・ウイルスという感染症に自身が感染したことで当事者意識が芽生え、清潔・不潔の区別は感染症から身を守るために徹底しなければいけないことだということを身をもって学ぶことができた。

seccamp (mini) in Akita 2018 に参加した話【訂正版】

seccamp (mini) in Akitaに参加しました。

セキュリティキャンプ2週間前から爆速でアセンブラを勉強しましたが、

当日の講義でアセンブラの知識はあまり使いませんでした。

午前のバイナリエクスプロイトの講義で使用したC言語脆弱性プログラムです。

当日の講義ではほとんど理解できなかったため、

クラスのガチプロにいろいろと聞きました。

以下は、聞いたことをそのまま書かせていただきました。

>>>VUL1>>>
#include <stdbool.h>
#include <stdio.h>
typedef struct {
    char name[100];
    bool is_admin;
} Profile;
int main() {
    Profile profile = {0, false};
    printf("Enter your name: ");
    scanf("%s", profile.name);
    printf("Are you admin? ");
    getchar();
    char c = getchar();
    if (c == 'y' && profile.is_admin) {
        puts("Goooooooooooooood!!! You are hacker!!!!");
        exit(0);
    } else {
        puts("Hi, noob.");
        exit(0);
    }
}

vul1は構造体の目盛りの確保に仕方について。
Profileはchar name[100]の後にすぐis_adminのメモリを確保する。
つまり、name[100] (つまり101番目)とやると、is_adminの場所を参照してしまう。
scanfは文字列の長さをいちいちチェックしない。
そこで、Enter your name:のところで101文字打ってあげて(101文字目ではname[100]に'\0'が入り結局falseになる)、name[100]を参照させ、is_adminの値を書き換えてしまえばよい。


>>>VUL2>>>
#include <stdio.h>
 
typedef struct {
    char name[16], age;
} person;
 
person alan = {"Alan Turing", 12};
 
void check_age(char age) {
    if(alan.age != age) {
        printf("You don't cheating me. Haha.\n");
        exit(1);
    }
}
 
int main(void) {
    int age = 0;
    printf("Hello\n");
    printf("Enter your age>");
    scanf("%d", &age);
    check_age(age);
     
    if(age >= 18) {
        printf("I allow %s to drink!\n", alan.name);
        return 0;
    }
    printf("Sorry, you cannot drink.\n");
    return 0;
}

vul2はキャストについて。
intとcharは格納できる値の範囲が違う。
charの範囲を超えた値を入れたint型変数をcharにキャストすると、
値がおかしなことになる。
intは4byte、charは1byteの型。
だから、int ->charのキャストはint型変数の後ろ1byteがcharに代入される。
int型の0xdeadbeefはcharにキャストすると、
後ろの1byte分が0x0cであれば何でもよい。
0xaaaaaa0c
0x1237890c
0x0a0b0c0c
だから268(0x0000010c)を打てばよい
(ただし12(0x0000000c)は18以上では無いため今回のコードでは、はずれ)


>>>VUL3>>>
#include <stdio.h>
#include <stdlib.h>
 
int randarr[3] = {0};
int next_rand = 0;
 
void init_arr(void) {
    for(int i = 0; i < 3; i++) {
        randarr[i] = rand();
    }
    next_rand = rand();
}
 
int main(void) {
    int n = 0;
    srand(time(NULL));
    init_arr();
    printf("can you guess me?");
    for(int i = 3; i; i--) {
        printf("you can see number log. enter number(1-3) rest(%d)>", i);
        scanf("%d", &n);
        printf("%d\n", randarr[n]);
    }
    printf("enter guess number >");
    scanf("%d", &n);
    if(next_rand == n) {
        printf("You are hacker!\n");
    } else {
        printf("oh no.");
    }
}

vul3はグローバル変数のメモリの確保の仕方について。
next_randはrandarr[3]と参照すれば、next_randの値が見れる。
だから3打って上げれば、next_randの値が見れる。
したがって、3と打ってあげれば、
next_randの数字が出てくるのでそれを打てばよい。


>>>VUL4>>>
#include <stdio.h>
 
void exec_shell(void) {
    printf("hacked!\n");
}
 
int main(void) {
    char input[256] = "";
    printf("this is a simple echo program - enter text and hack this!\n");
    printf("hint: main = %p, exec_shell = %p, input[256] = %p\n", main, exec_shell, input);
    for(;;) {
        if(!gets(input)) return 0;
        puts(input);
    }
}

vul4はスクリプト言語やらなんやらを使った覚えがあるが詳しいことは知らん!!

pythonのファイル名一括変換はgrobを使うと便利だよ~っていうだけの話

 grob.grob("./フォルダ名/*")

これだけで、フォルダにあるファイルをすべて読み込んでくれます。
今回は、ファイル1つ1つに連番を付けてファイル名を一括変換してみました。

import os
import glob

n=1
files = glob.glob('./フォルダ名/*')


for f in files:
    ftitle, fext = os.path.splitext(f)
    os.rename(f, str(n)+"_name"+fext)
    n+=1

Bing Seach API バージョン7.0でスクレイピングやってみた

#画像をスクレイピングする
# -*- coding:utf-8 -*-
#数学ライブラリをインポート
import math

#URL等を操るために使う関数
import requests

#URLから画像を保存したりするときの処理に使う
import imgutil

#1秒待機するために使う
import time
 
# image save path
#ユーザーからJBを起動
#Cドライブに新たに下記のフォルダが作られる
path = "/path/to/save"
imgutil.mkdir(path)
 
#エンドポイント
url = "https://api.cognitive.microsoft.com/bing/v7.0/images/search"
 
# parameters
#ほしい画像のキーワード
query = "ほしい画像のキーワード"
#何枚の画像をダウンロードするのか
count = 150      # 1リクエストあたりの最大取得件数 default:30 max:150
mkt = "ja-JP"   # 取得元の国コード
 
num_per = 8    # 重要:リクエスト回数(count * num_per=取得画像数)
offset = math.floor(count / num_per)    # ループ回数
 
#自分のAPIキー
subscriptionKey="自分のAPIキー"    # Bing Search API Key
 
headers = {'Ocp-Apim-Subscription-Key':subscriptionKey}
 
for offset_num in range(offset):
    #q:検索ワード
    #count:1リクエストあたりの取得件数
    #offset:データを取得開始するインデックス
    #mkt:結果の取得元となる国コード
    params = {'q':query,'count':count,'offset':offset_num*offset,'mkt':mkt}
    r = requests.get(url,headers=headers,params=params)
    #結果はJSON形式で取得されます。
    data = r.json()
    #キー「value」の配列として、
    for values in data['value']:
        #各「contentURL」の値が画像のURLとなる。あとはこのURLから画像をダウンロードする。
        image_url = values['contentUrl']
        try:
             #imgutilはgithubからソースコードをダウンロードしてきて、spyderに貼り付け、同じ階層内に入れておく
            imgutil.download_img(path,image_url)
        except Exception as e: #エラーの場合の処理
            print("failed to download image at {}".format(image_url))
            print(e)
    time.sleep(1) #1秒待機

Java Scriptによるブロック崩し

〜
[index.html]
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>ブロック崩し</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!--canvasにはゲームを描画-->
  <!--幅480px,高さ320px-->
  <canvas id="myCanvas" width="480" height="320">
  </canvas>
  <!--ゲームを制御するJSを書く-->
  <script src="main.js"></script>
</body>
</html>
[main.js]
//変数の宣言
//<canvas>要素への参照をcanvasに保存
let canvas=document.getElementById("myCanvas");
//2D描画コンテキストを保存するためにctx変数を作成
let ctx=canvas.getContext("2d");

//円の中心のx座標を定義
let x=canvas.width/2;
//円の中心のy
let y=canvas.height-30;

//xを描画した後に小さな値を加え、ボールが動いているように見せるための変数。
let dx=2;
//yを描画した後に小さな値を加え、ボールが動いているように見せるための変数
let dy=-2;

//計算を簡単にするために、描画される円の半径をもつballRadiusという変数を定義
let ballRadius=10;

//パドルの高さ
let paddleHeight=10;

//パドルの幅
let paddleWidth=75;

//パドルのx軸上の開始地点
//(キャンバスの右端の座標ーパドルの横幅)/2
let paddleX=(canvas.width-paddleWidth)/2;

//右側のボタンが押された
//最初、制御ボタンが押されていないため、デフォルトの値はfalseで初期化しておく。
let rightPressed=false;

//左側のボタンが押された
//最初、制御ボタンが押されていないため、デフォルトの値はfalseで初期化しておく。
let leftPressed=false;

//ブロックを定義
//ブロックの行の数
let brickRowCount=5;
//ブロックの列の数
let brickColumnCount=5;
//ブロックの幅
let brickWidth=75;
//ブロックの高さ
let brickHeight=20;
//
let brickPadding=10;
//キャンバスの上端からのブロック相対位置
let brickOffsetTop=30;
//キャンバスの左端からのブロックの相対位置
let brickOffsetLeft=30;

//1次元目の配列を宣言
let bricks=[];


//宣言終了

//変数の宣言終了
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//ボールを定義する関数
function drawBall(){
  //ボールを描画
  //draw()関数の中に下記のコードを追記する。
  //描画コードの始め
  ctx.beginPath();
  //円の描画
  //(円の中心のx座標、円の中心のy座標、円の半径、開始角度と終了角度、πの二乗)
  //arc()メソッド内で変数xと変数yを使うようにdraw()関数を書き換える。
  //ballRadius=描画される円の半径
  ctx.arc(x,y,ballRadius,0,Math.PI*2);
  //ctx.fillstyleに色を記憶。
  ctx.fillStyle="#0095DD";
  //fill()メソッドは、配列中の開始インデックスから終了インデックスまでの要素を固定値で設定する。
  ctx.fill();
  //描画コードの終わり
  ctx.closePath();

}
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//壁に当たったかどうかの判定
function judge(){
  //左右の壁の当たり判定
  //左の壁 (x+dx<0)
  //(今いるx座標+移動するx方向の変化量)<(キャンバスの左端の座標+ボールの半径)
  if(x+dx<ballRadius){
    dx=-dx;
  }
  //右の壁(x+dx>canvas.width)
  //(今いるx座標+移動するx方向の変化量)>(キャンバスの右端の座標-ボールの半径)
  else if(x+dx>canvas.width-ballRadius){
    dx=-dx;
  }

  //上下の壁の当たり判定
  //上の壁(y+dy<0)
  //(今いるy座標+移動するy方向の変化量)<(キャンバスの上端のy座標+ボールの半径)
  if( y+dy<ballRadius){
    dy=-dy;
  }
  //下の壁(y+dy>canvas.height-ballRadius)
  //(今いるy座標+移動するy方向の変化量>(キャンバスの高さ-ボールの半径)
  else if(y+dy>canvas.height-ballRadius){
    //ボールがパドルの左端と右端の間にあるか確認する
    //ボールのx座標 > パドルの左端のx座標 であり、ボールのx座標 < パドルの左端のx座標+パドルの横幅
    if(x>paddleX&&x<paddleX+paddleWidth){
      dy=-dy;
    }
    else{
      //アラート表示
      alert("GAME OVER");
      //再度読み込む(更新、リロード同じ)
      document.location.reload();
    }
  }
}
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//パドルを描画する関数
function drawPaddle(){
  //命令の始まり
  ctx.beginPath();
  //四角形の定義(パドルのx軸上の開始地点、キャンバスの下端ーパドルの高さ、パドルの横幅、パドルの高さ)
  ctx.rect(paddleX,canvas.height-paddleHeight,paddleWidth,paddleHeight);
  //ctx.fillStyleに四角形の色を記録
  ctx.fillStyle="#0095DD";
  //fill()メソッドは、配列中の開始インデックスから終了インデックスまでの要素を固定値で設定
  ctx.fill();
  //命令の終わり
  ctx.closePath();
}
//キーボードのキーのどれかに対してkeydownイベントが発生したとき(どれかが押されたとき)、keyDownHandler()関数が実行
document.addEventListener("keydown",keyDownHandler,false);
//キーボードのキーのどれかに対して、keyUpイベントが発生したとき(どれかが押された状態から離されたとき)、keyUpHandler()関数が実行される
document.addEventListener("keyup",keyUpHandler,false);

//---------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//ボタンが押されたときの処理
function keyDownHandler(e){
  //どちらの関数も変数eで表されるイベントをパラメータとしてとる。
  //keyCodeは押されたキーについての情報を持っている。(右カーソルキー=39)
  if(e.keyCode==39){
    //キーが押されたとき、その情報は変数に保存される。
    //キーが押されたときは、変数rightPressesの値がtrueに書き換わる。
    rightPressed=true;
  }
  //どちらの関数も変数eで表されるイベントをパラメータとしてとる。(e:event:これにより有用な情報が手に入る。)
  else if(e.keyCode==37){
    //キーが押されたとき、その情報は変数に保存される。
    //キーが押されたときは、変数rightPressesの値がfalseに書き換わる。
    leftPressed=true;
  }
}

//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//あらゆるボタンが押されている状態から離されたときの処理
function keyUpHandler(e){
  debugger;
  //どちらの関数も変数eで表されるイベントをパラメータとしてとる。
  //keyCodeは押されたキーについての情報を持っている。(右カーソルキー=39)
  if(e.keyCode==39){
    //キーが押された状態から離されたとき、その情報は変数に保存される。
    //キーが押された状態から離されたとき、変数rightPressedの値がtrueからfalseに書き換わる。
    rightPressed=false;
  }

  //keyCodeは押されたキーについての情報を持っています。
  else if(e.keyCode==37){
    //キーが押された状態から離されたとき、その情報は変数に保存される。
    //キーが押された状態から離されたとき、変数rightPressedの値がtrueからfalseに書き換わる。
    leftPressed=false;
  }
}
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//パドルを動かす処理
function movepaddle(){
  //パドルが縁から出てしまった時の処理
  //canvasの境界内でのみ動くようにする
  //右カーソルが押されている+パドルの左端のx座標<キャンバスの右端ーパドルの幅
  if(rightPressed&&paddleX<canvas.width-paddleWidth){
    paddleX+=7;
  }
  else if( leftPressed && paddleX>0){
    paddleX-=7;
  }
}
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//無限に続く setInterval の性質のため、draw()は10ミリ秒おきにずっと、あるいは私達が止めるまで呼ばれ続ける。
setInterval(draw,10);
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//1つの2次元配列で、すべてのブロックを記録する。
//2次元配列はブロックの列(c:Column)を含んでいる。
//また、列は行(r:Row)を含み、行はそれぞれのブロックが描画される画面上のx座標とy座標を持つオブジェクトを含んでいる。
//ブロックを描画する関数
function drawBricks(){
  //1次元目のループ
  //brickColumnCount=5より、5列のブロック
  for(let c=0;c<brickColumnCount;c++){
    //入れ子(2次元目の配列を加える)
    bricks[c]=[];
    //brickRowCount=3より、3行のブロック
    for(let r=0;r<brickRowCount;r++){
      //bricks[c][r]のx座標に0を紐づける
      //bricks[c][r]のy座標に0を紐づける
      //x座標とy座標の初期化
      //statusプロパティを追加
      bricks[c][r] = { x: 0, y: 0, status:1};
      //当たったブロックは消えるようにする
      if(bricks[c][r].status==1){
        //列の数*(ブロックの幅+余裕スペース)+左端からの相対位置
        let brickX=(c*(brickWidth+brickPadding))+brickOffsetLeft;
        //行の数*(ブロックの高さ+余裕スペース)+上端からの相対位置
        let brickY=(r*(brickHeight+brickPadding))+brickOffsetTop;
        //ブロックのx座標を代入
        bricks[c][r].x=brickX;
        //ブロックのy座標を代入
        bricks[c][r].y=brickY;

        //命令の始まり
        ctx.beginPath();
        //四角形の定義
        ctx.rect(brickX,brickY,brickWidth,brickHeight);
        //ctx.fillStyleに四角形の色を記録
        ctx.fillstyle="#0095DD"
        //fill() メソッドは、配列中の開始位置から終了位置までの要素を固定値で設定する。
        ctx.fill();
        //命令の終わり
        ctx.closePath();
      }
    }
  }
}

//衝突検出関数
function collisionDetection(){
  for(let c=0;c<brickColumnCount;c++){
    for(let r=0;r<brickRowCount;r++){
      //変数bはブロックオブジェクトを保存する
      //新たな変数bを宣言し、その中にbricks[c][r]を代入していく。
      let b=bricks[c][r];
      if(b.status==1){
        //色々な計算
        //ボールのx座標がブロックのx座標より大きい
        //ボールのx座標がブロックのx座標とその幅の和より小さい
        //ボールのy座標がブロックのy座標より大きい
        //ボールのy座標がブロックのy座標とその高さの和より小さい
        if(x>b.x&&x<b.x+brickWidth&&y>b.y&&y<b.y+brickHeight){
          dy=-dy;
          b.status=0;
        }
      }
    }
  }
}

//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
//ボールを描画する関数
function draw(){

  //削除コード
  //このメソッドは4つのパラメータをとる。
  //四角形の左上端のx,y座標と四角形の右下端のx,y座標。
  //この四角形で囲われた領域にある内容全てが消去される。
  ctx.clearRect(0,0,canvas.width,canvas.height);

  //ブロックを描画
  drawBricks();

  //衝突検出を有効に
  collisionDetection();

  //ボールを定義する関数
  drawBall();

  //パドルの動きを定義
  movepaddle();

  //パドルを描画する
  drawPaddle();

  //パドルの動きを定義
  movepaddle();

  //壁に当たったかどうかを判定する関数
  judge();

  //xの値を+2して更新する
  x=x+dx;
  //yの値を-2して更新
  y=y+dy;
}
[style.css]
*{
  padding:0;
  margin:0;
}

canvas{
  background:#eee;
  display:block;
  margin:0 auto;
}

Jupyter Notebook

 Jupyter Notebookは、ブラウザ上でコードを実行するためのインタラクティブな環境です。探索的なデータ解析をする際には非常に有用なツールであり、データサイエンティストに広く利用されています。Jupyter Notebookは様々なプログラミング言語をサポートしていますが、私のブログで取り扱うのはPythonだけです。またJupyter Notebookは、コードやテキスト、画像を簡単に取り込むことができます。