つけじょにーのすぱげていコード

主に、競技プログラミング、セキュリティのお勉強の際に書いたすぱげていコードを書き込みます

簡単なオセロ

ざーっと書いて、まだテストもろくにしてないので、バグだらけだと思います
一応アップしておきます

//簡単なオセロ(プレイヤーが、正確に石を置く想定)
#include <bits/stdc++.h>
#define MAX_W 8
#define MAX_H 8
using namespace std;
string board[MAX_W]; //盤面 e...empty(空) w...white(白) b...black(黒)
//上、右上、右、右下、下、左下、左、左上
//0  1    2   3    4  5    6  7
int fdx[] = {0, 1, 1, 1, 0, -1, -1, -1}; //x軸方向
int fdy[] = {1, 1, 0, -1, -1, -1, 0, 1}; //y軸方向
char side[] = {'W', 'B'};

//初期化
void init() {
    for(int r = 0; r < MAX_H; r++) {
        for(int c = 0; c < MAX_W; c++) {
            board[r][c] = 'e';
        }
    }
    board[3][3] = side[0];board[4][4] = side[0];
    board[3][4] = side[1];board[4][3] = side[1];
}

//処理すべきか否か
bool judge(int x, int y, int dir, char whichSide) { //始点、方向、白か黒か
    x += fdx[dir]; y += fdy[dir]; //すぐ隣なら処理は必要なし
    while(true) {
        x += fdx[dir]; y += fdy[dir];
        if((x < 0 || x >= MAX_W) || (y < 0 || y >= MAX_H)) break;
        if(board[y][x] == whichSide) {
            return(true); //処理せよ
        }
    }
    return(false); //処理するな
}

//盤面を出力
void print() {
    puts("-------------------------");
    for(int r = 0; r < MAX_H; r++) {
        for(int c = 0; c < MAX_W; c++) {
            printf("%c |", board[r][c]);
        }
        putchar('\n');
        puts("-------------------------");
    }
}

int count() {
    int black = 0;
    for(int r = 0; r < MAX_H; r++) {
        for(int c = 0; c < MAX_W; c++) {
            if(board[r][c] == side[1]) black++; //黒なら
        }
    }
    return(black);
}

//勝敗判定
void commit() {
    int black = count(), white = 64 - black;
    puts("結果発表");
    printf("白:%d\n黒:%d\n", white, black);
    if(white > black) printf("白の勝利!");
    else              printf("黒の勝利!");
}

void solve(int x, int y, char whichSide) {
    board[y][x] = whichSide;
    for(int r = 0; r < 8; r++) {
        if(judge(x, y, r, whichSide)) {
            x += fdx[r]; y += fdy[r];
            while(board[y][x] != whichSide) {
                board[y][x] = whichSide;
                x += fdx[r]; y += fdy[r];
            }
        }
    }
    print();
}

int main(void) {
    init();
    int which = 0;
    int x, y;
    print();
    while(cin >> x >> y, !(count() == 0 || count() == 64)) {
        solve(x, y, side[(which++)%2]);
    }
    commit();
    return(0);
}

Arduino&Processingのシリアル通信による、楽器作成

競技プログラミングやセキュリティとは異なりますが・・・
授業でやったのでメモ書きf:id:tukejonny:20141124232644p:plain

Arduino

void setup() {
  Serial.begin(19200);
}

void loop() {
  int val = analogRead(0);
  Serial.println(val);
  delay(250);
}

・Processing

import processing.serial.*;
import ddf.minim.*;
import ddf.minim.signals.*;

PFont myFont;
Minim minim;
Serial arduino;
AudioOutput out;
int currentTime, prevTime;
int x = 250, y = 250;
void setup() {
  size(500, 500);
  arduino = new Serial(this, Serial.list()[2], 19200);
  arduino.bufferUntil('\n');
  minim = new Minim(this);
  out = minim.getLineOut(Minim.STEREO);
  prevTime = millis();
  //delay(5);
  currentTime = millis();
}


void fadeToBlack() {
  noStroke();
  fill(0, 10);
  rectMode(CORNER);
  rect(0, 0, width, height);
}

void draw() {
  for(int r = 0; r <= 360; r++) {
    ellipse(x * cos(r), y * sin(r), 5, 5);
    fill(255, 0, 0);
  }
  fadeToBlack();
}
String indata = "";

void serialEvent(Serial port) {
  try {
    indata = port.readStringUntil('\n');
    if(indata != null) {
      indata = trim(indata);
      int cdsVal = Integer.parseInt(indata);
      /*
      if(cdsVal >= 700) {
        currentTime = millis();
        if(currentTime - prevTime > 1) {
          out.playNote("C4");
        }
        prevTime = currentTime;
      }
      */
      // many sounds
      if(cdsVal >= 900) {
        out.playNote("A3");
        x = 100; y = 100;
      } else if(cdsVal >= 850) {
        out.playNote("B4");
        x = 200; y = 200;
      } else if(cdsVal >= 800) {
        out.playNote("D4");
        x = 300; y = 300;
      } else if(cdsVal >= 750) {
        out.playNote("F#4");
        x = 400; y = 400;
      } else if(cdsVal >= 700) {
        out.playNote("G3");
        x = 500; y = 500;
      }
      
    }
  } catch(Exception e) {
    e.printStackTrace();
  }
}

写真、伝わりますでしょうか・・・
すっごい汚い上に、回路図の記法もろくに知らない無知さが露呈してしまっているのですが・・・
大きさの都合上、図形の中に文字を避けたのがいくつかあります
まぁ、こんな感じの回路を組んで、Processing, Arduino、それぞれ別のポートを選んでいただいて、cdsの上に手をかざしたりすると音が鳴ります
また、暗さによって音が変化します

書庫作りコマンド

tarコマンドについてメモ書き

//必須(どちらか)
//c = create(書庫作成)
//x = extract(書庫抽出)
//t = test(書庫表示:lsコマンドみたいな感じで表示)

//オプション
//z = gzip(gzip形式の場合、圧縮及び解凍にgzipを用いる)
//v = verbose(作成、抽出時にファイル一覧を出力)
//f = File(作成、抽出するファイルを指定)default値=/dev/rmt0

tar czvf example.tar.gz test1.txt test2.txt         //圧縮
tar xzvf example.tar.gz                             //解凍
tar tzvf example.tar.gz                             //出力

シンボリックリンクについて

自分にとって今の所使う機会が少なく、久しぶりに使うと毎回同じミスをしてしまうのですが、

ファイルを作ってからリンクさせる
のではなく
リンクファイルを作成するコマンドです

なので、touchやvimなど使う必要はなく、lnコマンドの引数にちゃんと対象ファイルと作成ファイル名を指定してやれば勝手に作ってくれます

書き方は ln -s [対象ファイル名] [作成するシンボリックリンクファイル名]
です

ln -s ../admin/index.txt index.txt

AES(Advanced Encryption Standard)

AESというのはDESに代わって新しく定められた共通鍵暗号標準です

厳しい審査の元、多くの暗号化アルゴリズムから5つが選び抜かれました
MARS, RC6, Rijndael, Serpent, Twofish

この中でもっとも優秀であったのはRijndaelで、晴れてAESに選定されました
このRijndaelは複雑な仕組み(SPN構造)で暗号化を行います

入力:128ビットとします(128~256まで32bit単位で選択)
①SubBytes
256個の換字対応表を元に、1バイトごとに変換を行います

②ShiftRows
バイト単位に規則的にごちゃまぜする。

③MixColumns
4バイトの値に対してビット演算を行う

④AddRoundKey
ラウンド鍵とXORする

以上です。疲れましたか? これ1ラウンドです(笑)
見ての通り複雑な暗号化をしていますが、実はこれには数学的構造が用いられています
それってどういうことか? 数式で表せるなら、数学で解読できちゃいます
けど、あくまでこれは可能性で今の所不可能です。
解読できちゃってたらAESとして今も使われてるわけないよね(笑)

XORの性質

XOR (排他的論理和)は面白い性質を持っているんです。
具体的になんだというと、例えば平文123があるとします。

int plain = 123;

これに対し、12という鍵を使って暗号化(XOR)します

int key = 12;
int cipher = plain ^ key;

そして、再度同じ鍵を使って複合化(XOR)します

int re_plain = cipher ^ key;

するとびっくり、平文と同じになります。
このように、XORを使う場合、平文は可逆の性質(用語ではない。自分の適当な造語です)を持ちます。