mas9612's notes

プログラミングなどいろいろ.

Base64のデコード・エンコード

Webの世界などで使用されているBase64のデコード・エンコードについて.
CTF (Capture The Flag) でも使用されることがあるので,軽くまとめてみた.

UNIXコマンド

エンコード

Base64コマンドを使用する.

$ echo 'base64 encode' | base64
YmFzZTY0IGVuY29kZQo=

-iオプションを使用すると,ファイルから文字列を読み込んでエンコードする.
-oオプションを使用すると,結果をファイルに書き込む.

$ base64 -i input.txt -o output.txt

input.txtの中身

base64 encode

output.txtの中身

YmFzZTY0IGVuY29kZQo=

デコード

-Dオプションをつける.

$ echo 'YmFzZTY0IGVuY29kZQo=' | base64 -D
base64 encode

エンコードと同じく,-iオプションと-oオプションは有効.

Python

標準ライブラリであるbase64モジュールを使用する.

エンコード

base64.b64encode()メソッドを使う.

>>> import base64
>>> s = 'base64 encode'
>>> base64.b64encode(s.encode('utf-8'))
b'YmFzZTY0IGVuY29kZQ=='

デコード

base64.b64decode()メソッドを使う.

>>> import base64
>>> encoded = b'YmFzZTY0IGVuY29kZQ=='
>>> base64.b64decode(encoded)
b'base64 encode'

どちらのメソッドも引数,返り値ともにバイトオブジェクトということに注意.

Pythonでsqlite

Pythonでデータベースを使ってみたかったので,標準ライブラリに含まれているsqlite3モジュールを触ってみた.

サンプルコードはこちら.
GitHubにもあげました.

# -*- coding: utf-8 -*-

import sqlite3

dbname = 'database.db'

conn = sqlite3.connect(dbname)
c = conn.cursor()

# executeメソッドでSQL文を実行する
create_table = '''create table users (id int, name varchar(64),
                  age int, gender varchar(32))'''
c.execute(create_table)

# SQL文に値をセットする場合は,Pythonのformatメソッドなどは使わずに,
# セットしたい場所に?を記述し,executeメソッドの第2引数に?に当てはめる値を
# タプルで渡す.
sql = 'insert into users (id, name, age, gender) values (?,?,?,?)'
user = (1, 'Taro', 20, 'male')
c.execute(sql, user)

# 一度に複数のSQL文を実行したいときは,タプルのリストを作成した上で
# executemanyメソッドを実行する
insert_sql = 'insert into users (id, name, age, gender) values (?,?,?,?)'
users = [
    (2, 'Shota', 54, 'male'),
    (3, 'Nana', 40, 'female'),
    (4, 'Tooru', 78, 'male'),
    (5, 'Saki', 31, 'female')
]
c.executemany(insert_sql, users)
conn.commit()

select_sql = 'select * from users'
for row in c.execute(select_sql):
    print(row)

conn.close()

以下,サンプルコードの解説を少し.

データベースへ接続

データベースに接続するには,sqlite3.connect()メソッドを使用する.

conn = sqlite3.connect(dbname)

sqlite3.connect()メソッドではConnectionオブジェクトが作成される.
SQL文を実行するには,ConnectionオブジェクトからさらにCursorオブジェクトを作成する必要がある.

c = conn.cursor()

このCursorオブジェクトを使用することでデータベースに対して様々なコマンドを実行することができる.

SQLの実行

SQL文を実行するには,Cursorオブジェクトのexecute()メソッドを使用する.

c.execute(sql[, parameters])

第1引数のSQL文に?を埋め込んだ場合は,第2引数で?にセットしたい値をタプルで渡す.

Example

user = (1, 'Taro', 20, 'male')
c.execute('insert into users (id, name, age, gender) values (?,?,?,?)', user)

こうすることで,SQLの?部分にタプル内の値がそれぞれ当てはめられ,最終的に以下のようなSQL文が実行される.

insert into users (id, name, age, gender) values (1, 'Taro', 20, 'male')

なお,一度に複数のSQLを実行したい場合は,executemany()メソッドを使用し,第2引数にタプルのリストを渡す(サンプルコード参照).

変更をデータベースに保存

execute()メソッドやexecutemany()メソッドでデータベースに追加・削除などを行った後には,必ずcommit()メソッドを呼び出す.このメソッドを呼び出さずにデータベースを閉じてしまうと,変更が保存されない.

conn.commit()

データベースを閉じる

プログラムの最後には忘れずにデータベースコネクションを閉じます.これにはclose()メソッドを使用する.このメソッドは自動的にcommit()を呼び出さないことに注意.

conn.close()

Pythonで日付を使う

Pythonのdatetimeモジュールについて少し勉強した. 今回はdateオブジェクトのみ.

Python公式ドキュメントより

datetime モジュールでは、日付や時間データを簡単な方法と複雑な方法の両方で操作するためのクラスを提供しています。日付や時刻を対象にした四則演算がサポートされている一方で、このモジュールの実装では出力の書式化や操作を目的とした属性の効率的な取り出しに焦点を絞っています。

date オブジェクト

datetime.date(year, month, day)

すべての引数が必要.引数で指定した日時のdateオブジェクトが作成される.

date.today()

現在のローカルな日付を返す.

date.fromtimestamp(timestamp)

引数に与えられたPOSIXタイムスタンプに対応するローカルな日付を返す.timestampがプラットフォームのC関数 localtime() がサポートする値の範囲から外れていた場合,OverflowErrorを送出する可能性がある.localtime() 呼び出しが失敗した場合にはOSErrorを送出する可能性がある.

date.replace(year, month, day)

キーワード引数で指定されたパラメタが置き換えられたdataオブジェクトを返す.

date.weekday()

月曜日を0,日曜日を6として曜日を整数で返す.

date.isoweekday()

月曜日を1,日曜日を7として曜日を整数で返す.

date.strftime(format)

formatで指定された書式文字列に合わせて,日付を表現する文字列を返す.

>>> import datetime
>>> datetime.date(2000, 1, 1)   # 2000年1月1日を表すdateオブジェクトを作成
datetime.date(2000, 1, 1)
>>> datetime.date.today()   # 今日の日付を表すdateオブジェクトを作成
datetime.date(2016, 5, 6)
>>> d = datetime.date.today()   
>>> d
datetime.date(2016, 5, 6)
>>> d.replace(year=1990)    # dateオブジェクトのyearを変更
datetime.date(1990, 5, 6)
>>> d.weekday() # 曜日を整数で返す(月曜日を0として)
4
>>> d.isoweekday()  # 曜日を整数で返す(月曜日を1として)
5
>>> d.strftime('%Y-%m-%d')  # 引数に与えられた書式で表示
'2016-05-06'