新しいフォルダー(1)

メモです。よろしくおねがいします。

[文字コード] 一般化可変長整数

一般化可変長整数

国際化ドメイン名では, マルチバイト文字のドメイン名がDNS上でASCII文字にエンコードされてやり取りが行われる.

そのときに使われるエンコーディング方式はPunycodeと呼ばれ, Punycodeでのエンコード・デコード処理の一部にこの一般化可変長整数と呼ばれる仕組みが利用されている.

数値と一般化可変長整数の対応を以下に示す.

数値(10進数表記) 一般化可変長整数
0 a
1 ba
2 ca
... ...
34 8a
35 9a
36 bba
37 cba
... ...
70 9ba
71 bca
72 cca
... ...
1260 99a
1261 bbb
1262 cbb
... ...
31885 99z
31886 bb0a
... ...
44135 999a
44136 bb0b
... ...

一般化可変長整数では, aが0, zが25, 0が26, 9が35を表し, リトルエンディアンのため, 一番右側の桁が最上位桁となる.

また, 一般化可変長整数には桁ごとに閾値が設定されており, 数値(10進数表記)から一般化可変長整数への変換は以下の式によって求められる.

数値(10進数表記) = 1桁目 + 2桁目 * 35 + 3桁目 * 1225 + 4桁目 * 12250

例えば, ひらがなの「あ」の一般化可変長整数l8jを10進数の整数に変換する場合, 11 + 34 * 35 + 9 * 1225 = 12226となる.

Punycodeでは, 1文字目は128からの差分で文字を表現するルールとなっているため, 128 + 12226 = 12354 = 0x3042 = U+3042となり, Unicodeでの「あ」を表現しているということが分かる.

また, 各桁に次の文字が使われていたらそこで数値の終了を表す.

数値
a
a
a - z
a - z

さらに, マルチバイト文字の2文字目以降は桁の重み付けのルールが変わる.

次も近くの文字が採用されるという前提でエンコード後の表現ができるだけ短くなるように

  • 数値(10進数表記)から一般化可変長整数への変換式
  • 数値の終了を意味する文字

が変更される.

[文字コード] Punycode

Punycode

Punycode(ピュニコード, プニコード)とは, 国際化ドメイン名で使用されるエンコーディング方式で, RFC 3492で定義され, RFC 5891で更新されている.

Adam M. Costello氏によって考案され, 仮称はAMC-ACE-Zであった.

ASCII文字で対応できる文字をそのまま利用することで全体的な文字数を減らす努力がなされている.

また, Base64などに比べ高い圧縮率のエンコーディング方式である.

デコード手順

xn--3B-ww4c5e180e575a65lsy2bを例にデコードを行う.

最終的なデコード結果は『3年B組金八先生』となる.

1. 接頭辞を取る

Punycodeエンコードされた文字列は接頭辞としてxn--が付加されるため, デコード時にはこれを取り外す.

xn--3B-ww4c5e180e575a65lsy2b -> 3B-ww4c5e180e575a65lsy2b

2. ASCII文字とマルチバイト文字を分ける

3B-ww4c5e180e575a65lsy2bの内, -(ハイフン)よりも前の文字はASCII文字であるため, デコードの対象にならない.

3B-ww4c5e180e575a65lsy2b -> ww4c5e180e575a65lsy2b

3. デコード処理

ww4c5e180e575a65lsy2bの部分は一般化可変長整数と呼ばれる仕組みでエンコードされているため, これを通常の10進数に戻す.

ww4c5e180e575a65lsy2b -> 62042, 139, 16683, 34821, 14592, 42088

次に, 62042Unicodeスカラ値と挿入位置を計算する.

// Unicodeスカラ値の計算
n = 128
n += 62042 / 3
n = 20808 = U+5148 = 先

// 挿入位置の計算
62042 mod 3 = 2

この計算から, nが「先」の文字コードで挿入位置が2であることが分かったため,

添字 文字
0 3
1 B
2

となる.

次に, 139Unicodeスカラ値と挿入位置を計算する.

// Unicodeスカラ値の計算
n += (((2 + 1) + 139) / 4)
n = 20808 + 35
n = 20843 = U+516B = 八

// 挿入位置の計算
((2 + 1) + 139) / 4 = 2

このとき, (((2 + 1) + 139) / 4)における262042 mod 3 = 22で, 1は処理上加算される値である.

この計算から, nが「八」の文字コードで挿入位置が2であることが分かったため,

添字 文字
0 3
1 B
2
3

となる.

続く16683, 34821, 14592, 42088Unicodeスカラ値と挿入位置も同様の計算方法によって求められる.

エンコード手順

3年B組金八先生』を例にエンコードを行う.

最終的なエンコード結果は"xn--3B-ww4c5e180e575a65lsy2b"となる.

1. 数値化する

文字 16進数表記 10進数表記
3 U+0033 51
U+5E74 24180
B U+0042 66
U+7D44 32068
U+91D1 37329
U+516B 20843
U+5148 20808
U+751F 29983

2. ASCII文字とマルチバイト文字を分ける

文字 16進数表記 10進数表記
3 U+0033 51
B U+0042 66
文字 16進数表記 10進数表記
U+5E74 24180
U+7D44 32068
U+91D1 37329
U+516B 20843
U+5148 20808
U+751F 29983

3. マルチバイト文字をUnicodeスカラ値順に昇順ソートする

文字 16進数表記 10進数表記
U+5148 20808
U+516B 20843
U+5E74 24180
U+751F 29983
U+7D44 32068
U+91D1 37329

4. エンコード処理

delta, n, m, c, hの5つの変数を用いる.

  • delta: 各Unicodeスカラ値のエンコード後の値を格納する変数
  • n: 次のソートされたUnicodeスカラ値を格納するときに現在のUnicodeスカラ値を格納しておく変数
  • m: ソートされたUnicodeスカラ値を順に格納する変数
  • c: ソート前のUnicodeスカラ値を順に格納する変数
  • h: 何文字目の処理かを格納する変数

なお, deltaの初期値は0であるが, ソート後のUnicodeスカラ値を選択したときにdelta += (m - n) * hが格納される.

また, nの初期値は128である.

hの初期値は今回の場合,

添字 文字
0 3
1 B

のように0文字目と1文字目はすでに決まっているので2が格納される.

// 初期化
n = 128
h = 2
delta = 0

// deltaの計算
h++
delta += (m - n) * h
delta += (20808 - 128) * 3
delta = 62040

// nの計算
n += 1
n = 20809

次にソート前のUnicodeスカラ値の並びである51, 24180, 66, 32068, 37329, 20843, 20808, 29983とソート後のUnicodeスカラ値の1つ目である20808を順に比較する.

文字 10進数表記 比較 比較対象「先」 delta h
3 51 < 20808 62041 3
24180 > 20808 62041 3
B 66 < 20808 62042 3
32068 > 20808 62042 3
37329 > 20808 62042 3
20843 > 20808 62042 3
20808 = 20808 0 4
29983 > 20808 0 4
// deltaの計算
delta = (m - n) * h
delta += (20843 - 20809) * 4
delta = 137

// nの計算
n += 1
n = 20844

先と同じように比較する.

文字 10進数表記 比較 比較対象「先」 delta h
3 51 < 20843 138 4
24180 > 20843 138 4
B 66 < 20843 139 4
32068 > 20843 139 4
37329 > 20843 139 4
20843 = 20843 0 5
20808 < 20843 1 5
29983 > 20808 1 5

同様にdeltaの計算を続けると, 最終的に62042, 139, 16683, 34821, 14592, 42088となる.

これに一般化可変長引数の仕組みを利用して変換し, 接頭辞と3Bを繋げると, xn--3B-ww4c5e180e575a65lsy2bとなる.

[文字コード] ホモグラフ攻撃

モグラフ攻撃

モグラフ攻撃(同形異字語攻撃)とは, URLのホスト名の文字として, 真正なサイトに酷似した異なる文字を用いて偽装し, 偽サイトに誘導するスプーフィングの一種である.

IDNホモグラフ攻撃

国際化ドメイン名(IDN: Internationalized Domain Name)を使用したホモグラフ攻撃のことを特にIDNホモグラフ攻撃と呼ぶことがある.

ドメイン名に使用できる文字は, 原則としてアルファベット(A - Z), 数字(0 - 9), ハイフン(-), ドット(.)のみであるが, 国際化ドメイン名ではUnicode及び非ASCII文字をPunycodeによりエンコードして利用できる.

半角英字(ラテン語)と形が酷似した

などが悪用される.

Unicodeにはゼロ幅スペースやゼロ幅非接合子, 双方向テキストに関する制御コードなどの悪用できそうな文字が定義されているが, これらはおおむね国際化ドメインには使用できない.

モグラフ攻撃の例

正: GOOGLE.COM
偽: G0OGLE.COM(半角数字の0(ゼロ)が半角英大文字のO(オー)に偽装)

正: google.com
偽: googIe.com(半角英大文字のI(アイ)が半角英小文字のl(エル)に偽装)

正: microsoft.com
偽: rnicrosoft.com(半角英小文字のr(アール)とn(エヌ)を繋げて半角英小文字m(エム)に偽装)

正: apple.com
偽: appie.com(半角英小文字のi(アイ)が半角英大文字のl(エル)に偽装)

IDNホモグラフ攻撃の例

正: wikipedia.org
偽: wikipedia.org(全角英小文字のa(エー)が半角英小文字のa(エー)に偽装)

正: wikipedia.org
偽: wíkipedia.org(アキュート・アクセントを付加した英小文字í(アイ)が半角英小文字のi(アイ)に偽装)

正: 朝日.com
義: 朝曰.com(曰が日に偽装)

[PHP] コンストラクタとデストラクタ

コンストラクタ

コンストラクタはクラスをインスタンス化したときに暗黙的にコールされる.

PHPでは__construct()というマジックメソッドで実現されている.

コンストラクタは一般的にプロパティの初期化などに用いられる.

<?php
class Foo {
    public function __construct($name = 'Anonymous') {
        $this->name = $name;
    }
}

デストラクタ

デストラクタはインスタンスが消滅するときに暗黙的にコールされる.

インスタンスの消滅するときとは, 具体的にはどの変数からも参照されなくなったときのことを指す.

PHPでは__destruct()というマジックメソッドで実現されている.

<?php
class Foo {
    public function __destruct() {
        echo 'This instance has been deleted.'
    }
}

[アーキテクチャ] x86アーキテクチャ

x86アーキテクチャに関するメモ.

x86アーキテクチャ

x86アーキテクチャとは, Intel社が開発したマイクロプロセッサのシリーズ名.

このシリーズのプロセッサは8086 -> 80186 -> 80286 -> i386 -> i486 -> Pentiumの順にリリースされたため, この名前で呼ばれている.

8086

8086は, 1978年に発売されたx86シリーズ初のプロセッサで, 16ビットプロセッサである.

従来の8ビットプロセッサ(8008, 8080, 8085)では接続可能なメモリが最大で64KBと少ない点を補うべく, データバス幅が16ビット, アドレスバスが20ビットに拡張され, 接続できるメモリの容量が最大1MBに増加した.

80186

80186は, 1982年に発売された16ビットプロセッサである.

8086にクロックジェネレータ, 割り込みコントローラ, タイマ, DMAコントローラ, チップセレクタなどの周辺回路を統合し, 1チップ化したことで, コストの低下と消費電力の削減が実現した.

DMAコントローラーが従来と異なることから, 当初見込んでいたデスクトップPCとしての採用は殆どなく, 8086の後継のプロセッサとしては失敗に終わったが, 消費電力を極力削減する必要のあるモバイルPCや組み込み機器などに採用された.

他にも, CMOS化による消費電力の削減を実現した80C186, 接続できるメモリを16MBに拡張した18677, 動作電圧を3Vに下げパワーマネジメント機能を追加した80C186EX, 動作クロックを25MHzまで引き上げられるようにした80C186XLなどの派生製品が存在する.

80286

80286は, 1982年に発売された16ビットプロセッサである.

8086を大幅に改良し, 約4倍の高速化を実現した.

従来互換のリアルモードに加えて新たに高速なプロテクトモードが追加され, アドレスバスも24ビットに拡張され, 16MBまでのメモリを扱えるようになった.

また, 80286にはPGA(Pin Grid Array)と呼ばれるパッケージの裏にピンが出ているタイプ, PLCC(Plastic Leaded Chip Carrier)と呼ばれるパッケージの側面からピンが出ているタイプ, LCC(Leadless Chip Carrier)と呼ばれるパッケージの裏に端子が並ぶ板状タイプの3種類が存在した.

8086の流れで爆発的にヒットしたため, Intelの他にもAMDIBMなども互換プロセッサを製造した.

i386

i386(80386)は, 80286の後継で1985年に発売されたx86シリーズ初の32ビットプロセッサである.

他にも, 1988年にデータバス幅を16ビットとした廉価版のi386SX(80386SX), それに伴いi386から改称されたi386DX(80386DX), ノートPCに適するように安全なレジューム機能やクロックの停止機能が追加されたi386SL(80386SL)などの派生製品が存在する.

レジスタのデータ長が従来の16ビットから32ビットに拡張されたため, ソフトウェアが対応していればより高速な処理が可能となった.

従来との互換性も確保されているため, 16ビットプロセッサ向けのソフトウェアも殆どそのまま動作する.

i386で導入された32ビットの命令セットアーキテクチャ(ISA: Instruction Set Architecture)はその後も引き継がれている.

i486

i486(80486)は, i386の後継で1989年に発売されたプロセッサである.

基本的にはi386の仕様を受け継いでいるが, 大幅な性能の向上が図られ, 従来は外部に付属していた数値演算用のコプロセッサであるFPU(Floating-Point Unit)やキャッシュメモリをプロセッサ内部の回路に統合するなどの改良が施された.

他にも, FPUを省いた廉価版のi486SX(80486SX), それに伴いi486から改称されたi486DX(80486DX), i486SXとi486DXのそれぞれでプロセッサ内部が外部クロックの2倍で動作するi486SX2とi486DX2, プロセッサ内部が外部クロックの3倍で動作するi486DX4, ノートPCに適したi486SLなどの派生製品が存在する.

Pentium

Pentium(ペンティアム)は, i486の後継で1993年に発売されたプロセッサである.

8086以降のプロセッサとの互換性を維持しつつ高速化が図られている.

MMX機能を追加した製品はMMX Pentiumと呼ばれ, これと区別するために旧製品は無印Pentiumなどと呼ばれることがある.

i486DX2と比べ, 約3倍にあたる310万個のトランジスタから構成され, 内部処理は32ビットだが, データバス幅は64ビットである.

パイプライン方式により2つの命令を並列実行できるようになっている.

[PHP] マジックメソッド

マジックメソッド

マジックメソッド(特殊関数)とは, インスタンスがある特定の条件を満たしたときに明示的にコールしなくても暗黙的にコールされるメソッドのこと.

メソッド名の先頭に__(アンダースコア2つ)が付加されているのが特徴.

__construct()はクラスをインスタンス化したときにコールされる.

プロパティの初期化処理などによく利用される.

<?php
class Foo {
    public function __construct($name = 'Anonymous') {
        $this->name = $name;
    }
}

[PHP] ショートタグ

short_open_tag = on

short_open_tag = onは, <?php<?で始められるようにするための, php.iniの設定.

short_open_tag = offが推奨であるのは, XMLの記法である<? ?>が誤動作する可能性を排除するためである.

現状でもshort_open_tag = offが推奨されている.

ショートタグ

<?=<?php echoのショートタグで, PHP 5.4.0以降, short_open_tagの設定に関わらず有効である.

すなわち, 非推奨であるshort_open_tag = onに影響されず, 開始タグを省略して記述できる.