ANA国内線【PR】

辞書型のスコープ

変数のスコープを記載したが、辞書型の場合、多少異なっている。

dic = {}
dic["TEST0"] = 0
var = 0
def func(dic, var):
  dic["TEST0"] = -1
  var = 10
func(dic, var)
print dic["TEST0"]
print var
としたとき、var = 0 となるが、dic["test0"] = -1 となる。辞書型は、参照渡しになるらしい。

# by ex_n-imai | 2010-10-26 01:22 | Python

ubuntu に subversion をインストールする

python でいろいろなコードを書きためてきたので、そろそろ(ようやく)バージョン管理ソフトウェアを導入しようと思い、ubuntu に subversion をインストールしてみた。

まず、apt-get で、関係パッケージをインストールする。
sudo apt-get install subversion subversion-tools libapache2-svn

次に、subversion のリポジトリを格納するディレクトリを作成する。
sudo mkdir /home/svn/
ここで、注意しなければならないのが、このディレクトリ名である。apache に定義する Location (より正確には、DocumentRoot + Location + リポジトリ名)と、実在のディレクトリ名が同一になった場合、クライアントからのアクセス時にエラーが発生する。
よって、ここでは、DocumentRoot(自分の場合は、/home/www-data/www/)とは、まったく異なる場所にディレクトリを作成した。

次に、apache の設定を変更する。/etc/apache2/mods-available/dav_svn.conf を開き、以下の記載を追加する。
<Location /svn>
 DAV svn
 SVNParentPath /home/svn/
</Location>
記載後、apache を再起動すれば、一通りの設定は完了となる。

/home/svn/ へ移動し、sudo svnadmin create (リポジトリ名)により、リポジトリを作成する。
クライアントから適当なツールでリポジトリにアクセスできれば、インストール成功である。


# by ex_n-imai | 2010-10-11 01:24 | Ubuntu

Python でステガノグラフィ(第8回)

各ピクセルのビット値を取得する関数を作成する。
def getBMPPlaneData(bgr_data, i, j, targetplane, show_force = False):
  i = ord(bgr_data[(i, j)]) & targetplane
  if show_force == True:
    if i != 0x00: i = 0xff
  return chr(i)
bgr_dataは、readBMPData 関数で取得したRGBの各要素とし、(i, j) は取得対象ピクセルの座標とする。
また、targetplane により、取得対象ビット値を指定する。0x01であれば、最下位ビットを取得し、0x80であれば最上位ビットを取得する。
オプションとした show_force は、強制的に最も明るい色を返すためのパラメータである。前回、最も暗い緑色を強制的に白色に変更したが、これは、show_force = True により実現している。

# by ex_n-imai | 2010-10-06 04:47 | Python

Python でステガノグラフィ(第7回)

前回も記述したが、BMP画像の1Pixelは、3Byteから構成されており、各々、青・緑・赤の要素が組み合わさっている。また、各Byteのビット値により、色調を調整している。

例えば、前回のサンプルデータの緑要素の最上位ビット(0x80)を抽出すると、次の画像となる。

次に3ビット目を抽出した画像は、次のようになる。

最下位ビットを抽出した画像は、次の画像である。


このように、各ビット値は各色の色調(明るさ)を定義している。

さて、最下位ビットの画像であるが、一見真っ黒の画像に見えるが、上述したとおり、実際は、最も暗い緑色の画像である。
そこで、最も暗い緑色で描かれている箇所を、強制的に白色に変換してみる。

砂嵐のような画像となったが、実際は、このような画像が描かれていたわけである。

前回のサンプルデータの画像と比較すると、最下位ビットの画像は、その面影すら分からない。
すなわち、ビットが下位の画像であれば、どのように変更しても、人間の目で判別できにくい、ということになる。

# by ex_n-imai | 2010-09-28 02:08 | Python

Python でステガノグラフィ(第6回)

詳細は記載しないが、前述したとおり、24bit BITMAP は 1pixel の色を 3byte = 24bit で表している。
実際の画像データから、緑色のデータのみを抽出する。
このとき、青色および赤色を表すデータ(各々1byte)は、0x00 とする。

以下が元画像である。(都合上、JPEGである。)

次が緑色のデータを抽出した画像である。


色の色調は、各バイトの bit の ON-OFF で決定する。すなわち、色調は 256 種類あるということになる。

# by ex_n-imai | 2010-08-28 01:57 | Python

Python でステガノグラフィ(第5回)

話を BITMAP に戻そう。
BITMAPFILEHEADER および BITMAPINFOHEADER の読み書き関数がそろったところで、画像データを取り扱う。24bit BITMAP のデータ構造の詳細については、他サイトに詳しく記載されているので、割愛する。

まず、画像の1行のデータサイズを算出する関数を作成する。
def calcLineSize(bmpinfoheader):
  linesize = bmpinfoheader["biWidth"] * bmpinfoheader["biBitCount"] / 8
  if linesize % 4 != 0: linesize = ((linesize / 4) + 1) * 4
  return linesize
24bit BITMAP の1行のデータサイズは、画像の横幅×24bit/3 ではないことに留意する。

さて、24bit BITMAP の 1pixel は、青色、緑色、赤色の 1Byte データから構成される。
(だから、3色×8bit = 24bit BITMAP ということ)
読み込み時には、各色別に座標データ付きで取得することとする。
def readBMPData(fo, bmpinfoheader):
  blue_data = {}
  green_data = {}
  red_data = {}
  fo.seek(size_BMPFILEHEADER + size_BMPINFOHEADER)
  size_line = calcLineSize(bmpinfoheader)
  buf = size_line - (size_line / 3) * 3
  for i in xrange(bmpinfoheader["biHeight"]):
    for j in xrange(size_line / 3):
      blue_data[(i, j)] = fo.read(1)
      green_data[(i, j)] = fo.read(1)
      red_data[(i, j)] = fo.read(1)
    fo.seek(buf, 1)
  return blue_data, green_data, red_data

# by ex_n-imai | 2010-08-05 04:19 | Python

Python でステガノグラフィ(第4回)

ちょっと横道にそれて、与えられたデータを 1Byte ずつ 1BIT ごとのリストに変換する関数を作る。
要は、0xFF 0x01 を [[11111111][10000000]] に変換する関数である。この関数の用途については、後述する。(右から 1BIT目、2BIT目・・・、8BIT目 とする。)

def ConvDataToListOfBit(data) と命名するが、この関数の作成でいろいろと悩んでいたのが、日曜プログラマの限界か?(:b)

たとえば、data が PDF や EXE などのバイナリデータである場合、for c in data とすれば、c は 1Byte であるのだが、data が 文字列の場合、文字コードの違いにより c は 1Byte から 3Byte まで取り得る可能性がある。

そこで、一旦 data を unsigned char の整数型に変換する。
fmt = "%dB" % (len(data))
list_uchr_data= struct.unpack(fmt, data)
これにより、list_uchr_data は、文字コードによらず、0 から 255 までの整数値のみを取り扱うデータとなる。
また、len(list_uchr_data) は、data のバイト長となる。

さて、リスト内包表記を用いて、bit_values = [2**j for j in range(8)] なるものを定義する。
展開すると、[1, 2, 4, 8, 16, 32, 64, 128] となるのだが、これは、各 BIT が ON になったときの値である。すなわち、1BIT目のみが ON の場合は 1 であり、7BIT目のみが ON の場合は、64 である。
これを用いて、与えられた 1Byte データの各 BIT の ON/OFF をチェックする。
c_list_bits = []
for value in bit_values: c_list_bits.append((c & value) / value)
c_list_bits には、8 つの 1 もしくは 0 の数値がリスト形式で格納され、右から 1BIT、2BIT、・・・、8BIT目の ON/OFF を表す。
なお、bit_values = [2**j for j in range(7, -1, -1)] とすると、左右が逆転したリストを得ることができる。

これらを組み合わせて、先ほどの関数を作成する。
bit_values = [2**j for j in range(8)]

def ConvDataToListOfBit(data):
  list_bits = []
  fmt = "%dB" % (len(data))
  list_uchr_data= struct.unpack(fmt, data)
  for c in list_uchr_data:
    c_list_bits = []
    for value in bit_values: c_list_bits.append((c & value) / value)
    list_bits.append(c_list_bits)
  return list_bits
たとえば、utf-8 の「文字String」を変換すると、[[0, 1, 1, 0, 0, 1, 1, 1], [0, 1, 1, 0, 1, 0, 0, 1], [1, 1, 1, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 1, 1, 1], [1, 0, 1, 1, 0, 1, 0, 1], [1, 1, 1, 0, 1, 0, 0, 1], [1, 1, 0, 0, 1, 0, 1, 0], [0, 0, 1, 0, 1, 1, 1, 0], [0, 1, 0, 0, 1, 1, 1, 0], [1, 0, 0, 1, 0, 1, 1, 0], [0, 1, 1, 1, 0, 1, 1, 0], [1, 1, 1, 0, 0, 1, 1, 0]] となる。

# by ex_n-imai | 2010-08-04 03:35 | Python

Python でステガノグラフィ(第3回)

readBMPFILEHEADER, readBMPINFOHEADER 関数に対して、writeBMPFILEHEADER, writeBMPINFOHEADER 関数を作成する。
双方の read 関数で出力した辞書型変数を引数にする仕様とする。
def writeBMPFILEHEADER(fo, dict_bmpfileheader):
  list_bmpfileheader = []
  for item in item_BMPFILEHEADER:
    list_bmpfileheader.append(dict_bmpfileheader[item])
  raw_bmpfileheader = struct.pack(struct_BMPFILEHEADER, *list_bmpfileheader)
  fo.seek(0)
  fo.write(raw_bmpfileheader)
dict_bmpfileheader[item] で、BITMAPFILEHEADER 構造体の項目順に値を取り出し、list_bmpfileheader へ追加して一旦リスト形式にしている。その後、struct.pack(struct_BMPFILEHEADER, *list_bmpfileheader) でバイナリデータに変更し、ファイル出力を行っている。

writeBMPINFOHEADER 関数も同様の構成となっている。
def writeBMPINFOHEADER(fo, dic_bmpinfoheader):
  list_bmpinfoheader = []
  for item in item_BMPINFOHEADER:
    list_bmpinfoheader.append(dic_bmpinfoheader[item])
  raw_bmpinfoheader = struct.pack(struct_BMPINFOHEADER, *list_bmpinfoheader)
  fo.seek(size_BMPFILEHEADER)
  fo.write(raw_bmpinfoheader)

# by ex_n-imai | 2010-06-17 06:05 | Python

Python でステガノグラフィ(第2回)

前回、BITMAPFILEHEADER 取得処理を関数化したので、同様に、BITMAPINFOHEADER 取得処理を関数化する。
# BITMAPINFOHEADER 情報
struct_BMPINFOHEADER = "<LllHHLLllLL"
item_BMPINFOHEADER = ("biSize", "biWidth", "biHeight", "biPlanes",
          "biBitCount","biCompression", "biSizeImage", "biXPixPerMeter",
          "biYPixPerMeter","biClrUsed", "biClrImporant")
size_BMPINFOHEADER = struct.calcsize(struct_BMPINFOHEADER)

def readBMPINFOHEADER(fo):
  fo.seek(size_BMPFILEHEADER)
  raw_bmpinfoheader = fo.read(size_BMPINFOHEADER)
  bmpinfoheader = struct.unpack(struct_BMPINFOHEADER, raw_bmpinfoheader)
  dic_bmpinfoheader = dict(zip(item_BMPINFOHEADER, bmpinfoheader))
   # OS/2 ヘッダの場合は空辞書
  if dic_bmpinfoheader["biSize"] != size_BMPINFOHEADER: return {}
  else: return dic_bmpinfoheader
構成は先の readBMPFILEHEADER 関数と同じである。

readBMPFILEHEADER 関数と readBMPINFOHEADER 関数により、ある BMP を読み込んだ結果、以下のような出力が得られる。
{'bfOffBits': 54, 'bfReserved1': 0, 'bfSize': 921654, 'bfType': 'BM', 'bfReserved2': 0}
{'biSizeImage': 921600, 'biCompression': 0, 'biXPixPerMeter': 3780, 'biPlanes': 1, 'biBitCount': 24, 'biYPixPerMeter': 3780, 'biSize': 40, 'biClrUsed': 0, 'biHeight': 480, 'biClrImporant': 0, 'biWidth': 640}
各構造体は、各々の項目名を KEY にした辞書に格納されている。

# by ex_n-imai | 2010-06-09 23:19 | Python

Python でステガノグラフィ(第1回)

Python でのステガノグラフィに挑戦してみる。
あまり大仰に構えてもダメなので、まずは最もお手軽と考えられる 24bit ビットマップ画像で構築する。

とりあえず、以前作成した BITMAPFILEHEADER 取得処理を関数化する。
# BITMAPFILEHEADER 情報
struct_BMPFILEHEADER = "<2sLHHL"
item_BMPFILEHEADER = ("bfType", "bfSize", "bfReserved1", "bfReserved2", "bfOffBits")
size_BMPFILEHEADER = struct.calcsize(struct_BMPFILEHEADER)

def readBMPFILEHEADER(fo):
  fo.seek(0)
  raw_bmpfileheader = fo.read(size_BMPFILEHEADER)
  bmpfileheader = struct.unpack(struct_BMPFILEHEADER, raw_bmpfileheader)
  return dict(zip(item_BMPFILEHEADER, bmpfileheader))

struct_BMPFILEHEADER は、struct モジュールのための構造体型情報を格納し、size_BMPFILEHEADER は、構造体サイズを格納する。

readBMPFILEHEADER 関数からの戻り値は、取り扱いし易いように辞書型(項目名:値)にしてみた。

# by ex_n-imai | 2010-05-26 05:21 | Python

< 前のページ 次のページ >